使用组件外部的数据更新Polymer Component

时间:2016-08-04 06:14:14

标签: socket.io polymer

这应该是一项非常正常的任务,但我错过了一些东西。

我正在尝试将Socket.io与Polymer [使用聊天应用程序]集成 - 决定将MessageList和单个messageItem更改为Polymer组件。   SocketIo公开了一个从服务器抛出的customEvent,它将消息作为数据发送,然后将其分配给自定义元素上的属性。

这是MessageList元素。

private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{ 
    try
    {
        DataOperation DO = new DataOperation();
        DataTable Dt;
        Dt = DO.GetPymntDetails(Convert.ToInt32(CmBxCompanyName.Selected Index), "SelectById");

        if (Dt != null)
        {
            txtCompanyId.Text = Dt.Rows[0].ItemArray[0].ToString();
            txt_mno.Text      = Dt.Rows[0].ItemArray[1].ToString();
            txt_add.Text      = Dt.Rows[0].ItemArray[2].ToString();
            txt_vno.Text      = Dt.Rows[0].ItemArray[3].ToString();
            txtCstNo.Text     = Dt.Rows[0].ItemArray[4].ToString();
            txt_eid.Text      = Dt.Rows[0].ItemArray[5].ToString();
         }
    }
}

在index.html页面 -

<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>

所有这些..无论何时客户端发送消息,self.messages - 发布消息总集,但自定义元素的“_messageListChanged”仅在第一次被调用。

有类似的问题 - Updating a polymer element property with data from API call

但是,分配数据仅适用于第一次。  此外,我希望能够不使用ajax-iron和东西来做到这一点。

3 个答案:

答案 0 :(得分: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)'
    ],

请注意,这种观察者只需要一个参数,一个更改记录。

  

您的观察者方法应接受单个参数。调用observer方法时,它会收到数组上发生的突变的更改记录。

答案 1 :(得分: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();

});

切片将创建新数组。它将触发数组中的所有更改。

答案 2 :(得分:-1)

请尝试将reflectToAttribute:true添加到您的messageList属性。

如果你还没有解决它,请尝试这样做

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

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

原因可能是javascript数组推送或切片不会反映在聚合物的脏检查中

如果您在聚合物组件中使用以下代码。你必须遵循聚合物的阵列变化,如

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;

    });