2014-01-21 10 views
7

Ich habe ein Array von Objekten, die in einem knockout Observable Array angeschlossen sind. Ich musste diesen Arrays anwenden Sortieren und ich lief in einige Verhalten, das ein wenig verwirrend ist.Knockout Observable Array mit Sortierung und Foreach Data-Binding

Mein erster Versuch betraf das Anwenden der Sortierung in der foreach-Datenbindung.
http://jsfiddle.net/wnfXV/

<ul data-bind="foreach: people.sort(function(l,r) { return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1)})">

dies die richtige Sortierung führt, aber ich verlieren die Fähigkeit, Elemente aus dem Array dynamisch hinzufügen/entfernen und das DOM-Update haben.

Wenn ich einen Satz Klammern hinzufügen, um auf das zugrunde liegende JavaScript-Array zuzugreifen, funktioniert alles einwandfrei.

<ul data-bind="foreach: people().sort(function(l,r) { return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1)})">

basierend auf einigen SO Antworten I gefunden, beendet I für die sortierten Array eine berechnete beobachtbaren Schaffung up. http://jsfiddle.net/wnfXV/2/

self.sortedPeople = ko.computed(function() { 
    return self.people().sort(function(l,r) { 
     return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1); 
    }); 
}); 

Dies funktioniert auch. Und ich brauche nicht einmal zu Daten-bind auf den berechneten beobachtbar, da sie sofort ausgeführt werden. Ich kann Array-Elemente verschieben und entfernen und das DOM wird entsprechend aktualisiert.

Allerdings, wenn ich den Code zu ändern:

self.sortedPeople = ko.computed(function() { 
    return self.people.sort(function(l,r) { 
     return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1); 
    }); 
}); 

Nun, ich bin in der Lage, Elemente in die Anordnung und das DOM-Updates zu schieben, aber die Daten werden nicht sortiert werden.

Ich denke diese Unterschiede beziehen sich auf die Verfolgung der Knockout-Abhängigkeit und den Unterschied zwischen dem Betrieb auf einem beobachtbaren Array und dem darunter liegenden nativen JavaScript-Array, aber es fällt mir schwer zu verstehen, warum sich das Verhalten ändert. Ich bin in der Lage, es zu bekommen zu arbeiten, aber ich bin auch neugierig, was am beste Praxis betrachtet wird.

Danke für jede Hilfe. :)

Antwort

1

In deiner JS Fiddle ist es, weil deine Foreach an Leute gebunden ist ... nicht an sortedPeople.

Der Grund, warum es das erste Mal sortiert ist, weil der Computer einmal ausgeführt wird ... aber nicht abonniert.

Die Berechnung endet jedoch wieder, wenn Sie die Klammer wegen einer Subskription für das zugrunde liegende Array verwenden.

Edit:

Wenn Sie die Klammer verwenden, wird die berechnete auf das Array abonnieren, wenn der beobachtbaren aufgerufen wird. Wenn sich das abonnierte Element ändert, wird die Berechnung erneut ausgeführt.

+0

Es könnte mehr deutlich, wenn man sein nur abonniert das beobachtbare Array anstelle der berechneten. Sie verwenden im Grunde die für sein Abonnement berechnet. http://jsfiddle.net/N9sGY/ – LameCoder

+0

Ja, das erklärt das letzte Beispiel, in dem Elemente hinzugefügt, aber nicht neu sortiert werden. Vielen Dank. Irgendwelche Ideen, warum die Push/Remove-Funktionalität nicht in der ersten Geige funktioniert, oder warum das Hinzufügen der Klammern es behebt? – ecozoic

+0

In der ersten Geige ist es im Grunde dasselbe. Da Sie die Klammer nicht verwenden, wird keine Subskription erstellt. Doing people.sort schließt im Prinzip den Mechanismus ein, der Änderungen vornimmt. – LameCoder

2

Problem Art in Ansichten verwenden, ist eigentlich nicht durch KO empfohlen, da mit diesem Ansatz observableArray.sort keine Abhängigkeit auf dem Array aufzubauen, so erhält die Bindung nicht aktualisiert.

Also, wenn Sie es Arbeit machen wollen, kann man

items.slice(0).sort() 

bei
für detaillierteren Blick verwenden https://github.com/knockout/knockout/issues/1380

Fiddle: http://jsfiddle.net/mbest/6dmAn/

Verwandte Themen