2016-04-03 17 views
1

Ich habe eine einfache Proof-of-Concept-Polymer 1.0 App gemacht, die mein Problem zeigt: JSBin.Detect Array Mutation

In meinem Problem verwende ich array mutation methods, um das Array zu ändern, das die Liste der Einkaufsartikel enthält.

Allerdings scheint dies nicht wie vorgesehen zu funktionieren. I tun erhalten Sie eine Änderung in dom-repeat und beim Drucken der Länge des Arrays. Aber Ich nicht bekomme das Änderungsereignis, wenn ich das Array selbst ausdrucken noch wenn ich es in einer Funktion verpacken.

Kurz gesagt, warum funktioniert das?

<p>Number of items: [[list.length]]</p> 

Und warum tut dies nicht Arbeit?

<p>Items inline: [[list]]</p>  
<p>Observe function : [[_observe(list)]]</p> 

Auch, wenn ich die folgende Zeile (in der JSBin) Kommentar-, scheinen die Dinge wie indened zu arbeiten. Aber ich mag es nicht, weil es ein bisschen hackisch ist.

app.notifyPath('list', app.list.slice()); 

ich gestolpert auf die slice() fix durch Lesen dieser Ausgabe: https://github.com/Polymer/polymer/issues/2068


EDIT

So, nachdem die Kommentare bewerten, ist die Antwort auf die Frage: „Ist das von Design "ist JA. Das Array selbst ändert sich nicht (da es nur eine Referenz ist), aber es ist die Eigenschaft do ändern. Deshalb zwingt das slice() das Neuladen, da es eine flache Kopie erstellt.

Aber, könnte man streiten, ob das in Ordnung ist. Ja, die Variable list ändert sich nicht per se. Aber das Setzen von [[list]] in den HTML-Code löst tatsächlich toString() aus. Und das Ergebnis dieser Funktion hat geändert.

Ich glaube, ich mit Huckepack die length Eigenschaft bin stecken jetzt ...

+0

Ihre jsbin Probe für mich in Chrom –

+0

funktioniert gut, wenn Sie sich fragen, warum Beobachter nicht ausgelöst, es nur, weil Link zum Objekt wird nur Link, und es sich nicht geändert haben, beobachten List.length und Return-Liste –

+0

oder Sie können Link zu Array in einigen var sichern, benachrichtigen ohne 2. Argument, und sofort mit backedUp Liste benachrichtigen, ich bin mir nicht sicher, was schneller, aber dieser Ansatz muss Array nicht klonen, und mehr darüber wird nicht tief brauchen Klon in komplexen Fällen. –

Antwort

2

Wie in den Kommentaren spielte auf die notifyPath und slice Anrufe werden eine flache Kopie des Arrays erstellen und eine andere Referenz zuweisen zurück zu die Variable list - löst eine Aktualisierung der Bindung aus. Ohne eine separate (watchable) Variable oder Unordnung mit Objektreferenzen zu haben, wäre die einzige andere Problemumgehung, die ich denken könnte, auf die list.length Eigenschaft anstelle der Liste selbst zu pendeln und diese durch eine Art von "Formatierung" zu übergeben Funktion. z.B.

<p>Items inline: [[format(list.length)]]</p> 
app.format = function(){ 
    return app.list.toString(); 
}; 

» Fiddle


Wie @zb wies darauf hin, könnten Sie auf diese erweitern und die Funktion wiederverwendbar mit jedem Array machen, indem Sie die entsprechende Variable als Argument übergeben zu:

<p>Items inline: [[format(list, list.length)]]</p> 
app.format = function(list){ 
    return list.toString(); 
}; 

» Fiddle

+1

Ich würde es bevorzugen http://jsbin.com/mocagujapi/1/edit?html,js, Ausgabe –

+1

Ye ich denke, dass es wiederverwendbar machen würde. Es ist ein bisschen wie ein Klotz, der Anwendungsfall ist ziemlich begrenzt. – Emissary

+0

@zb 'und @Emissary Ich habe meine Frage ein wenig aktualisiert. Aber das ändert wahrscheinlich nicht die Lösung für das Problem: huckepack die 'length'-Eigenschaft. – alesc