2012-04-03 6 views
0

Ich habe eine Anwendung, wo Objekte in einer von mehreren Listen sein können. Die Benutzeroberfläche für eine Liste muss jedes Element als auf einer der anderen Listen markiert markieren.Verfolgungslistenüberlappungen in knockoutjs

Eine grob vereinfachte Version von dem, was ich implementiert haben, ist dies:

function Item(id, panel) { 
    var that = this; 
    this.id = id; 
    this.viewModel = panel; 
    this.isSelected = ko.computed(function(){ 
     return panel.isSelected(that); 
    }); 
} 

function Panel() { 
    var that = this; 

    //my two lists 
    this.all = ko.observableArray(); 
    this.selected = ko.observableArray(); 

    this.isSelected = function(item){ 
     return _(that.selected()).find(function(thing){ 
      console.log("iterating"); 
      return thing.id == item.id; 
     }); 
    }; 
} 

var panel = new Panel(); 
ko.applyBindings(panel); 

//add some things to the list 
for(var i=0; i<40; i++){ 
    var item = new Item(i, panel) 
    panel.all.push(item); 
    //let's select some of them. note it's actually a different object 
    if (i % 2 == 0){ 
     panel.selected.push(new Item(i, panel)); 
    } 
}; 
​ 

Fiddle ist hier: http://jsfiddle.net/89j52/5/

Also, über die Seltsamkeit der Artikel einen Verweis aus auf die Platte geben, es macht auch furchtbar. Das liegt daran, dass jedes Mal, wenn Sie der ausgewählten Liste ein weiteres Element hinzufügen, der ausgewählte Status für alle die Elemente erneut berechnet; Beachten Sie, wie oft "iterierend" gedruckt wird. Ich verstehe, warum es das tut, aber es ist schmerzhaft.

Nun offensichtlich, es ist nicht wirklich müssen jedes Element jedes Mal, wenn ich eine hinzufügen. Ich könnte zum Beispiel eine Nachschlagetabelle für die Elemente speichern und dann einfach die richtigen aktualisieren, wenn etwas zur ausgewählten Liste hinzugefügt wird. Aber ich bin mir nicht sicher, wie ich das mit Knockouts beobachtbaren/berechneten Sachen verheiraten und das UI-Update nahtlos machen soll. Wie sollte ich das innerhalb von Knockouts Idiomen angehen?

Antwort

1

Was ist, wenn Sie isSelected regelmäßig beobachtet werden (nicht berechnet) konvertieren und aktualisieren Sie es jedes Mal, wenn Sie direkt Artikel zu ausgewählten Liste hinzuzufügen:

function select(item){ 
    panel.selected.push(item); 
    var itemInAll = _(panel.all()).find(function(thing){ 
     return thing.id === item.id; 
    }); 
    itemInAll.isSelected(true); 
} 

Nicht sehr elegant, aber auf jeden Fall effizienter. Sie müssen keinen Hinweis auf Panel in Artikel, auch zu halten. Hier ist der vollständige Code: http://jsfiddle.net/89j52/9/

+0

Ich landete etwas in diese Richtung. Ich möchte immer noch etwas glatter, aber es funktioniert gut. –