通过索引将元素分配给knockout.js observableArray的正确方法是什么?

时间:2013-08-05 03:37:40

标签: knockout.js ko.observablearray

我一直在关注淘汰赛的documentation observableArray,而且我无法弄清楚如何使用数组做一些最基本的事情:分配一个值按索引。

我尝试过的事情:(给oa = ko.observableArray([1,2,3])

  • oa(1, 10);
  • oa[1] = 10;
  • oa()[1] = 10;
  • oa.splice(1, 1, 10);

最后一个似乎有效,但我担心.splice()可能效率低下,因为它必须关注转移所有后续值。我宁愿只做基于索引的简单分配。

created a jsfiddle显示一个可观察的阵列很奇怪。

<ol data-bind="foreach: list">
    <li data-bind="text: $data"></li>
</ol>

<script>
    var model = {
        list: ko.observableArray([3, 5, 7])
    };

    ko.applyBindings(model);

    setTimeout(function() {
        model.list()[1] = 55;
        model.list.push(99);
        model.list()[2] = 77;
    }, 2000);
</script>

3 个答案:

答案 0 :(得分:5)

修改后在您的observable上应用 valueHasMutated 属性

setTimeout(function() {
    model.list()[1] = 55;
    model.list.push(99);
    model.list()[2] = 77;
    model.list.valueHasMutated();
}, 2000);

答案 1 :(得分:3)

当调用mutating方法或使用新数组初始化时,Observable数组会通知其侦听器更改(从而导致相应的视图更新)。

oa()[i] = x;
oa(oa());

您可以将其分解为扩展方法:

ko.observableArray.fn.setItem = function(index, newValue) {
    var items = this();
    items[index] = newValue;
    this(items);
};

foreach绑定非常智能,可以检测到只有一个元素被更改,并且不需要再次呈现其他节点。

答案 2 :(得分:1)

你在小提琴中分配价值的方式很好。如果您执行了model.list()对象的console.log(),则实际上可以看到数组的值已正确更新。

要记住的关键是文档中的以下内容:

  

关键点:observableArray跟踪数组中的对象,而不是那些对象的状态

     

简单地将对象放入observableArray并不会使该对象的所有属性本身都可观察到。当然,如果您愿意,您可以观察这些属性,但这是一个独立的选择。 observableArray只跟踪它所拥有的对象,并在添加或删除对象时通知侦听器。

这是您的视图未使用索引2中的新值更新的原因,因为它不是可观察的值。像这样的东西(快速和肮脏)将起作用:

var model = {
    list: ko.observableArray([ko.observable(3), ko.observable(5), ko.observable(7)])
};
model.list()[2](77); // Yeah, looks weird.