2016-08-04 70 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