2016-08-04 71 views
0

這應該是一個非常正常的任務,但我錯過了一些東西。使用組件外部的數據更新聚合物組件

我正在嘗試將Socket.io與Polymer [使用聊天應用程序]進行集成 - 決定將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鐵和東西。

回答

-1

請嘗試將reflectToAttribute:true添加到您的messageList屬性。

,如果你還沒有得到它解決了嘗試所以這

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

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

原因可能是JavaScript的陣推或切片不會聚合物的髒檢查

refelect如果您在聚合物組件中使用下面的代碼。你必須遵循聚合物的陣列變化,如

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

除了使用Polymer API for array mutations(正如Alon在他的回答中指出的),您需要安裝一個觀察者array mutations。您現在擁有的觀察者只會在分配新數組實例時觸發,而不會在您向陣列添加或移除元素時觸發。

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

請注意,這種觀察者需要一個參數,一個更改記錄。

您的觀察者方法應該接受一個參數。當您的觀察者方法被調用時,它會接收陣列上發生的突變的更改記錄。

+0

他在數組上拼接。不需要設置這種觀察者,並且他如何寫觀察者是可以的。但它也很好。 – Alon

+0

@Alon你說得對。然而,正如託尼19指出的那樣,拼接效率並不高。 – Maria