2011-06-22 8 views

答えて

8

通常、あなたはノックアウトでこのような何かをするだろう:

var viewModel = { 
    a: ko.observableArray(["a","b","c","d"]), 
    add_item: function() { 
     this.a.push("new" + this.a().length); 
    } 
}; 

viewModel.a_assoc = ko.dependentObservable(function() { 
    var result = {}; 
    ko.utils.arrayForEach(this.a(), function(item) { 
     result[item] = 1; 
    }); 
    return result; 
}, viewModel); 

だから、あなたは、オブジェクトへのあなたの配列をマッピングしdependentObservableを持っています。元の配列が更新されるたびに、オブジェクトが再構築されることに注意してください。したがって、ポストのメソッドよりも効率が悪いですが、オブジェクトが大幅に大きくならない限り、パフォーマンスの問題が発生する可能性は疑わしいです。ここ

サンプル:http://jsfiddle.net/rniemeyer/PgceN/

+1

ありがとうRPN。私のデータセットは2Kに成長するので、パフォーマンスは問題ではありません。 btw、ko.utilsにオンラインのリファレンスがありますか? –

+2

現在、utilsのドキュメントはありません。最高のリソースは、現在私のブログからです:http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html –

+0

素晴らしい。ありがとう! –

1

私はそれがパフォーマンスのためにボンネットの下に連想配列を使用するのが最善だと思います。また、(あなたが暗示したように)変更を追跡するためにobservableArrayを使用する必要があります(ノックアウトの仕組みなので)。

「ノックアウトフレンドリーな」連想配列を探しているなら、おそらくアイテムへの変更を追跡して、依存関係のチェーンに影響を与える方法が必要です。

http://jsfiddle.net/rz41afLq/2/

は、ここで私はその最適私のニーズ思い付いたものです。基本的には、キー値のペアをobservableArrayに格納し、標準の連想配列を使用して検索目的でコピーを格納します。

// VIEW MODEL 
var viewModel = { 

    // we have to use observable array to track changes 
    items: ko.observableArray([]), 

    // also use associative array for performance 
    _assoc: {}, 

    update_item: function(key, value) { 

     // use a true assoc array for performance 
     // _assoc[key] = ko.observable(value) 
     if (viewModel._assoc[key]) 
     { 
      // update observable (overwriting existing item) 
      viewModel._assoc[key].value(value); 
     } 
     else { 
      // Important: See how we wrap value with an observable to detect changes 
      this.items.push(viewModel._assoc[key] = { key: key, value: ko.observable(value) }); 
     } 
    } 
}; 

だから、このようなあなたの犬を救う:

update_item('dogs', ['kim', 'abbey', 'goldie', 'rover']); 
update_item('dogs', ko.observableArray(['kim', 'abbey', 'goldie', 'rover'])); 

(第2のみが必要とされますが、犬のリストにpop()またはpush()を呼び出し、UIを更新することを計画している場合は。もちろんupdate_itemと呼んで、いつでもアイテムを完全に更新することができます(この場合、それは観測可能である必要はありません)

値を検索するには、計算するために計算する:

var dogs = getValue('dogs'); 

その後できるだけ早く値が連想配列の変化の「犬」としてインデックスのように観察dogs()が更新され(と連鎖することができます)。このdogsは、もちろんUIにバインドできます。

var getValue = function(key) { return ko.pureComputed(function() 
{ 
    // reevaluate when item is added or removed to list 
    // not necessary if the value itself changes 
    viewModel.items();              

    var item = viewModel._assoc[key]; 
    return (item == null) ? null : item.value(); 

}, viewModel);