2016-08-04 9 views
0

Dies sollte eine ziemlich normale Aufgabe sein, und doch fehlt mir etwas.Aktualisieren von Polymer-Komponente mit Daten von außerhalb der Komponente

Ich versuche Socket.io mit Polymer zu integrieren [mit der Chat-Anwendung] - Entscheidung, die MessageList und die einzelnen messageItem als Polymer-Komponenten zu ändern. SocketIo legt ein customEvent offen, das vom Server ausgelöst werden soll. Die Nachricht wird als Daten gesendet, die dann einer Eigenschaft des benutzerdefinierten Elements zugewiesen wird.

Dies ist das MessageList-Element.

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

Auf der index.html-Seite -

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

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

    }); 

Mit all dies .. Jedesmal, wenn ein Client sendet eine Nachricht, die self.messages - Beiträge die Gesamtmenge von Nachrichten, aber die "_messageListChanged" der benutzerdefinierten Elemente wird nur beim ersten Mal aufgerufen.

Es gibt ähnliche Fragen - Updating a polymer element property with data from API call

jedoch die Daten durchsucht werden, funktioniert nur zum ersten Mal. Auch ich würde es gerne ohne Ajax-Eisen und so machen können.

Antwort

-1

versuchen Sie bitte reflectToAttribute:true zu Ihrer MessageList-Eigenschaft hinzuzufügen.

wenn Sie nicht noch es versuchen bekommen gelöst dieser

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

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

Grunde so könnte der JavaScript-Array Push oder Scheibe wird schmutzig Überprüfung

in Polymers nicht refelect wenn Sie unten Code in einer Polymerkomponente verwenden. Sie müssen folgen Array-Änderungen des Polymers wie

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

Das Problem ist, dass Sie Push verwenden. Polymer hat seine eigene Push-Funktion. Der reguläre Push löst nicht die Beobachter und alle Änderungsereignisse aus.

this.push('array',value) 

Aber für Sie, können Sie es wie folgt lösen:

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


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

}); 

Die Scheibe wird neues Array erstellen. Und es wird alle Änderungen im Array auslösen.

+1

Die Verwendung von 'self.messages.slice()' in jeder Chat-Nachricht ist sehr ineffizient und könnte für langwierige Konversationen kostspielig sein. – tony19

+0

dies gilt nur für sehr sehr lange Arrays, versuchen Sie und sehen Sie die Zeit, die es dauert, Array mit 1000 Objekte zu schneiden, wenn er will, schrieb ich die Lösung mit dem Druck von Polymer ... – Alon

+0

Was ich ging ist, eine andere Funktion ausgesetzt Auf das Element (wird von der JS aufgerufen), nimmt die neue Nachricht und schiebt es auf die MessageList, mit der Mutationsmethode, die Sie erwähnt haben. So funktioniert es jetzt. –

1

Zusätzlich zur Verwendung der Polymer API for array mutations (wie Alon in seiner Antwort darauf hingewiesen hat), müssen Sie einen Beobachter für array mutations installieren. Der Beobachter, den Sie jetzt haben, wird nur ausgelöst, wenn Sie eine neue Array-Instanz zuweisen, aber nicht, wenn Sie Elemente aus Ihrem Array hinzufügen oder entfernen.

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

Beachten Sie, dass diese Art von Beobachter ein einzelnes Argument, eine Änderungsaufzeichnung nimmt.

Ihre Beobachtermethode sollte ein einzelnes Argument akzeptieren. Wenn Ihre Beobachtermethode aufgerufen wird, erhält sie eine Änderungsaufzeichnung der Mutationen, die im Array aufgetreten sind.

+0

ist er Splice auf dem Array. es ist nicht erforderlich, diese Art von Beobachter einzustellen, und wie er den Beobachter geschrieben hat, ist in Ordnung. Aber es ist auch gut. – Alon

+0

@Alon Sie haben Recht. Tony19 wies jedoch darauf hin, dass Spleißen nicht so effizient ist. – Maria

Verwandte Themen