2016-08-04 10 views
0

これはかなり正常な作業でなければなりません。コンポーネントの外部からのデータを使用してポリマーコンポーネントを更新する

私はSocket.ioをPolymer [chatアプリケーションを使用して]と統合しようとしています - MessageListと個々のmessageItemをPolymerコンポーネントとして変更することを決定しました。 SocketIoはサーバーからスローされるcustomEventを公開します。このイベントはメッセージをデータとして送信し、カスタム要素のプロパティに割り当てられます。

これはMessageList要素です。

<link rel="import" href="/polymer/polymer.html"> 
<link rel="import" href="message.html"> 

<dom-module id='message-list'> 
<template> 

    <style> 

    </style> 

    <ul id="messages"> 
     <template is='dom-repeat' items="{{messageList}}" is="auto-binding"> 
      <li> 
       <message-item message = "{{item}}"></message-item> 
      </li> 
     </template> 
    </ul> 

</template> 
<script> 
    var messageListElement = Polymer({ 
     is : 'message-list', 
     properties : { 
      messageList : { 
       type : Array, 
       observer: '_messageListChanged', 
       reflect : true , 
       value : function() { 
        return [{'inputMessage' : 'Welcome to the Chat' , 
        'nickName' : 'System' , 'msgTime' : new Date()}] 
       } 
       //, notify : true 
      } 
     }, 

     _messageListChanged: function(newValue , oldValue) { 
      console.log("Data changed"); 
     }, 

     created : function() { 
      console.log("messagelist created"); 
     }, 

     ready : function() { 
      console.log("messagelist ready"); 
     }, 

     attributeChanged : function() { 
      console.log("messagelist attributeChanged"); 
     } 
    }); 
</script> 
index.htmlページで

- このすべてで

var self = this; 
socket.on('chatMessage' , function(msg) { 
     self.messages.push(msg); 
     console.log(self.messages); 

     document.querySelector('message-list').messageList = self.messages; 

    }); 

...いつでも、クライアントがメッセージを送信し、self.messages - ポストメッセージの合計セット、カスタム要素の "_messageListChanged"は、初めて初めて呼び出されます。

が同様の質問があります - Updating a polymer element property with data from API call

しかしデータを割り当て、初回のみ動作します。 また、私はajax-ironやstuffを使わずにやりたいと思っています。

答えて

-1

あなたのmessageListプロパティにreflectToAttribute:trueを追加してみてください。

あなたはまだそれがdocument.querySelector('message-list').messageList = self.myimmutedArray;

理由はjavascript配列のプッシュやスライスは、ポリマーの汚れが

をチェックするにはrefelectません可能性がありする前にこの

self.myimmutedArray JSON.parse(JSON.stringify(self.messages)) 

にしようとは解決されません場合ポリマーコンポーネントで以下のコードを使用するとします。ポリマーの配列の変化に従わなければならない

this.push('messages', {title:'hey'}); 

var self = this; 
socket.on('chatMessage' , function(msg) { 
     self.messages.push(msg); 
     console.log(self.messages); 

     document.querySelector('message-list').messageList = self.messages; 

    }); 
0

問題はプッシュを使用することです。ポリマーは、彼自身のプッシュ機能を持っています。定期的なプッシュは、オブザーバーとすべての変更イベントをトリガーしません。

this.push('array',value) 

しかし、あなたのために、あなたはこのようにそれを解決することができます

var self = this; 
socket.on('chatMessage' , function(msg) { 
    self.messages.push(msg); 


    document.querySelector('message-list').messageList = self.messages.slice(); 

}); 

スライスは、新しい配列を作成します。そして、配列内のすべての変更がトリガーされます。

+1

すべてのチャットメッセージに 'self.messages.slice()'を使用することは非常に非効率的で、長時間の会話にはコストがかかる可能性があります。 – tony19

+0

これは非常に非常に長い配列の場合にのみ当てはまります。1000オブジェクトの配列をスライスするのにかかる時間を見てください。ポリマーのプッシュを使って解決策を書いたければ... – Alon

+0

私が行ったことは、 (JSから呼び出される)要素上で、あなたが言及した突然変異方法を使用して、新しいメッセージを取り出し、それをmessageListにプッシュします。それで今はうまくいく。 –

1

を使用することに加えて(彼の答えでAlonが指摘したように)array mutationsのオブザーバーをインストールする必要があります。オブザーバは、新しい配列インスタンスを割り当てるときにのみ起動しますが、配列に要素を追加または削除するときには起動しません。

properties : { 
     messageList : { 
      type : Array, 
      value : function() { 
       return [{'inputMessage' : 'Welcome to the Chat' , 
       'nickName' : 'System' , 'msgTime' : new Date()}] 
      } 
     } 
    }, 
    observers: [ 
     '_messageListChanged(messageList.splices)' 
    ], 

この種類のオブザーバは、単一の引数、変更レコードを取ります。

あなたのオブザーバーメソッドは、1つの引数を受け入れる必要があります。オブザーバーメソッドが呼び出されると、配列上で発生した変異の変更レコードを受け取ります。

+0

は配列上でスプライスしますか?この種のオブザーバーを設定する必要はなく、オブザーバーを書いた方法は大丈夫です。しかし、それはまた良いです。 – Alon

+0

@Alonあなたは正しいです。しかし、tony19が指摘するように、スプライシングはそれほど効率的ではありません。 – Maria

関連する問題