2012-04-03 4 views
0

オブジェクトが複数のリストのいずれかにあるアプリケーションがあります。 1つのリストのUIは、各アイテムを他のリストのいずれかにあるものとしてマークする必要があります。knockoutjsでのリストの重複の追跡

私が実装したものを著しく単純化されたバージョンは、このです:

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)); 
    } 
}; 
​ 

フィドルはここにある:だからhttp://jsfiddle.net/89j52/5/

、パネルに出た項目に参照を与えることのすごみを超えて、それがひどく実行します。これは、選択したリストに別のアイテムを追加するたびに、の選択されたステータスをすべて再計算するからです。すべてアイテムです。 iteratingを何回印刷するかを気にしてください。なぜそれがそれをやっているのか理解していますが、痛いです。

明らかに、それは実際にはは私が追加を行うたびにチェックする必要はありません。たとえば、アイテムのルックアップテーブルを隠しておき、選択したリストに何かが追加されたら、正しいものを更新することができます。しかし、私はノックアウトの観察可能な/計算されたものにそれを結びつけ、UI更新を見せかけないようにする方法がわかりません。ノックアウトのイディオムの中でこれをどのように扱うべきですか?

答えて

1

あなたが定期的に観察できる(計算されていない)にisSelectedを変換し、直接あなたが選択したリストに項目を追加するたびに、それを更新した場合:非常にエレガントな、しかし間違いなく、より効率的ではありません

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

を。 パネルへの参照をの項目に保存する必要はありません。以下は完全なコードです:http://jsfiddle.net/89j52/9/

+0

私はこれらの行に沿って何かをやりました。私はまだ滑らかなものが好きですが、うまく動作します。 –

関連する問題