2016-06-23 13 views
2

Problem: Wir verwenden redux, um den Status in unserer App zu verwalten. Dies verursacht Probleme beim Rendern. Änderungen in Arrays (z. B. Entfernen) werden von dom-repeater nicht korrekt gehandhabt. Was passiert ist, dass Daten und die gestempelten Vorlagen durcheinander geraten.Polymer 1.5 Wie dom-repeat bei Verwendung unveränderlicher Datenstruktur gemeldet wird

Ich möchte eine Möglichkeit finden, dom-repeat Element über Array-Änderungen zu benachrichtigen.

<template is="dom-repeat" items="[[data.items]]"> 
    <repeater-item config="[[item]]" on-change="_onChange"></repeater-item> 
</template> 

Ich habe unveränderlichen Zustand in meiner Polymer-Anwendung, so kann ich diese Methoden nicht Mutation Polymer Array.

here is a plnkr

Was habe ich versucht:
1) this.set('data', newState);
Als Ergebnis, wenn ich das erste Element in meiner Datenarray ‚dom-repeat‘ ​​entfernen die letzte Vorlage <repeater-item> entfernen und Daten neu zuweisen dies wie:

template-1 receives data 2, 
template-2 receives data 3, 
... 

2) in der zweiten Versuch ich versuche zu notifySplices:

var splices = Polymer.ArraySplice.calculateSplices(newState.items, this.data.items); 
this.data = newState; 
this.notifySplices('data.items', splices); 

Ergebnis ist das gleiche

3) Aus irgendeinem Grund fast funktioniert die folgende ..

var splices = Polymer.ArraySplice.calculateSplices(newState.items, this.data.items); 
this.data.items = newState.items; 
this.notifySplices('data.items', splices); 

ergibt sich eine korrekte Templatentfernung aber hier erhalte ich einen Fehler:

VM47184 polymer-mini.html:2046 Uncaught TypeError: Cannot read property 'length' of undefined 

Was ist der richtige Weg, um 'dom-repeat' zu melden, wenn ein unveränderlicher Zustand verwendet wird?

Antwort

1

Ich konnte den Fehler für Option 3 verhindern; Das Hinzufügen des Polymer.Collection.get für das neue Array scheint den Fehler zu verhindern, der auftritt, nachdem die Methode abgeschlossen ist und Dom-Repeat die Änderungen wiedergibt.

_remove(id) { 
    var newState = { 
    items: this.data.items.filter(item => item.id !== id) 
    }; 

    // Polymer.Collection.get somehow prevents an exception _after_ notifySplices is called 
    Polymer.Collection.get(newState.items); 

    // Retro-actively calculate splices in Polymer fashion 
    var prev = (this.data.items || []); 
    var splices = Polymer.ArraySplice.calculateSplices(newState.items, prev); 

    // Change the data _without_ Polymer being aware of it (because it isn't a direct property of the element) 
    this.data.items = newState.items; 

    // Notify Polymer about the array changes so dom-repeat can re-use the correct templates 
    this.notifySplices('data.items', splices); 
} 

Sehen sie in Aktion: http://plnkr.co/edit/fFGWfL?p=preview

Ich weiß nicht, warum dies die Ausnahme verhindert, es eher eine zufällige Entdeckung war mehr als alles andere.

Aber das scheint immer noch wie eine suboptimale Lösung, da Sie das betroffene Array in einem Wrapper-Objekt verstecken müssen.