我认为最好在底层使用关联数组来提高性能。您还(正如您所提到的)需要使用 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']));
(第二个只有在你打算在狗列表上调用pop()或push()并且想要更新UI时才需要。当然你可以随时调用update_item来完全更新项目在这种情况下,它不需要是可观察的)
要查找一个值,您可以动态创建一个计算来获取它:
var dogs = getValue('dogs');
然后,一旦关联数组中索引为“dogs”的值发生变化,那么可观察的dogs() 就会更新(并且可以链接)。这个dogs observable 当然可以绑定到 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);