2012-04-13 3 views
2
Bindung

Ich habe eine KnockoutJS Vorlage, die etwa wie folgt aussieht:KnockoutJS Mapping-Update funktioniert nicht richtig mit <- ko foreach: -> Stil

<div data-bind="template: {name: 'testTemplate', data: people}"></div> 

<script id="testTemplate" type="text/html"> 
    <!--ko foreach: $data-->   
    <div class="items" data-bind="text: full() + ' updated at: ' + Date()"></div> 
    <!--/ko--> 
</script> 

Nach dem Ausführen von Nth Anzahl von Tests, erkannte ich, Das Erstellen einer solchen Vorlage ist fehlerhaft, da KnockoutJS die Vorlage jedes Mal aktualisiert, auch wenn sich die Daten nicht ändern.

Ich habe dies diese beiden Geigen mit dargestellt:

Wie Sie sehen können, wenn Sie die Last Anfangs Pfund oder aktualisierte Datenschaltflächen auf der foreach-Bindung laden, wird die Benutzeroberfläche nie erneut gerendert, es sei denn, die Daten ändern sich tatsächlich. Wenn Sie das Gleiche mit der Datenstilbindung tun, wird es jedes Mal neu gerendert.

Ich kann wirklich nicht herausfinden, was der Unterschied ist. Ich hatte den Eindruck, dass die Datenbindung genauso funktionierte wie foreach, aber mehr Kontrolle über das Objekt innerhalb der Vorlage erlaubte.

Der einzige Grund, warum ich es benutze ist, weil ich eine Reihe von verschachtelten Vorlagen habe, und ich musste näher an das eigentliche Objekt heranrücken. Ich sollte in der Lage sein, neu zu faktorisieren und von diesem Ansatz wegzukommen, aber ich frage mich immer noch, warum es ein Problem ist.

Sollte nicht die <!--ko foreach:--> das gleiche Muster honorieren, das die Foreach-Vorlagenbindung verwendet?

Antwort

3

Das Problem ist, dass Ihre Vorlagebindung ein Abonnement für Ihre people observableArray erstellt, da es als data übergeben wird. Wenn das Array people aktualisiert wird (Elemente verschoben/entfernt usw.), löst dies die Vorlagenbindung aus, um die Vorlage erneut zu rendern. In Ihrem Fall wird der gesamte Inhalt neu gerendert, sodass die foreach innerhalb der Vorlage nie eine Chance erhält, effizient zu sein.

Eine einfache Möglichkeit, dies zu vermeiden, ist sicherzustellen, dass die Vorlagenbindung Ihr people observableArray nicht auspackt. Sie können die Daten wie { myArray: people } übergeben und dann Ihre foreach auf myArray tun. Hier

ist ein Beispiel: http://jsfiddle.net/rniemeyer/bVPwM/4/

+0

Sie erkennen, jetzt bin ich nur versucht, mit einer Frage kommen Sie nicht :) beantworten kann. Haha ... ausgezeichnete Lösung! – farina

+0

Ich bemerkte das gleiche passiert mit farina

+0

'if' ist ein Wrapper für die Template-Bindung, also wäre ja das Verhalten ähnlich. –