2013-06-03 10 views
18

Ich habe Probleme, die foreach Bindung mit einer Sorte zu kombinieren. Ich habe eine Liste wie so gebunden:Knockout - Mit foreach und sort zusammen

<article data-bind="foreach: widgets"> 

Widgets ist ein einfaches obvservable Array:

var widgets= ko.observableArray(); 

Das funktioniert mir schön zu geben eine Liste meiner "Widgets". Wenn ich ein neues "Widget" zu dieser Liste hinzufüge, erscheint es dynamisch in der Liste durch Datenbindung.

Doch sobald ich zum Array hinzufügen Sortierung:

<article data-bind="foreach: widgets.sort(function (left, right) { return left.order() == right.order() ? 0 : (left.order() < right.order() ? -1 : 1); })"> 

Dann neu hinzugefügte Widgets nicht mehr in meiner Liste erscheinen - es sei denn, ich die Seite neu zu laden. (Die Sortierung funktioniert an dieser Stelle gut - wenn ich das Feld "Reihenfolge" aktualisiere, nach dem ich sortiere, werden die Elemente in meiner Liste dynamisch neu sortiert).

Wie kann ich mit der dynamischen Aktualisierung von neuen Objekten in meinem beobachtbaren Array dafür sorgen, dass die Sortierung gut funktioniert?

Ich verwende Breezejs, um meine Daten abzurufen, aber ich denke nicht, dass dies Auswirkungen auf dieses Szenario hat.

Antwort

29

Die observableArray.sort gibt das sortierte zugrunde liegende ("reguläre") Array zurück und keine observableArray, deshalb werden die Änderungen nicht auf der Benutzeroberfläche angezeigt.

Um die Sortierung und die Benutzeroberfläche aktualisieren zu lassen, müssen Sie eine ko.computed erstellen, die die Sortierung durchführt und die Berechnung in Ihrer Bindung verwendet. Denn die ko.computed hört auf die widgets Änderungen und Neuberechnung der Sortierung.

var widgets= ko.observableArray(); 

var sortedWidgets = ko.computed(function() { 
    return widgets().sort(function (left, right) { 
     return left.order() == right.order() ? 
      0 : 
      (left.order() < right.order() ? -1 : 1); 
    }); 
}); 

Dann können Sie es mit binden:

<article data-bind="foreach: sortedWidgets" /> 
+0

Dank -, die gut gearbeitet. Können Sie bitte Ihre Antwort aktualisieren, um "function()" am Anfang von ko.computed (innerhalb der ersten Klammern) einzufügen. Ich werde es dann als Antwort akzeptieren. – daveywc

+0

Wie kann ich dies dann für eine verschachtelte foreach, d. H. Eine foreach für eine Navigationseigenschaft eines der Widgets in meiner Top-Level-Liste, tun. In diesem Fall deklariere ich nicht explizit das beobachtbare Array, an das ich gebunden bin, so dass ich nicht sehen kann, wie ich diesen Ansatz verwenden soll. – daveywc

+0

Ich habe den Tippfehler in meiner Antwort behoben. Ich bin mit Breezejs nicht vertraut, aber ich denke, es kann so konfiguriert werden, dass diese benutzerdefinierten sortierten Eigenschaften für Sie erstellt werden. Anyway JS ist dynamisch, so dass Sie jedem vorhandenen Objekt neue Eigenschaften hinzufügen können. – nemesv