Knockout.js在字符串列表中的`foreach`中使用`value:`绑定 - 不会更新

时间:2012-11-12 19:48:27

标签: knockout.js knockout-2.0

以下a jsFiddle证明了以下问题:

给定一个(可观察的)字符串列表的foreach绑定,observable似乎不会更新为foreach中绑定的输入标记的更改。人们会期待他们。这是jsFiddle的例子:

HTML

<ul data-bind='foreach: list'>
    <li><input data-bind='value: $data'/></li>
</ul>

<ul data-bind='foreach: list'>
    <li><span data-bind='text: $data'></span></li>
</ul>

的Javascript

​var vm = { list: [ko.observable('123'), ko.observable('456')] };
ko.applyBindings(vm);​

在上面的示例中,可以预期更新第一个列表中的输入标记会导致observable更新。不幸的是,它们没有按预期更新,因为第二个列表未能反映对第一个列表所做的任何更改。

我确认在更改输入元素时实际上没有更新列表。 有趣的是,对可观察量的改变反映在两个列表中(正如人们所预料的那样)。即,vm.list[1]("444")将更新两个列表的第二个元素。

我的回忆是Knockout 2.0.0没有这个问题,尽管我有待纠正。我没有在Knockout代码中找到任何文档,Google或评论,这些代码产生了为什么这不起作用或如何达到预期结果的任何迹象。

为什么这不能按预期工作,是否有任何不需要更改数据结构的变通方法?

2 个答案:

答案 0 :(得分:15)

我使用value: $parent.list[$index()]解决了这个问题,如this jsFiddle所示。新绑定看起来像这样:

<ul data-bind='foreach: list'>
    <li>
        <input data-bind='value: $parent.list[$index()]' />
    </li>
</ul>

可以通过自定义绑定来改进这一点。

另请参阅Knockout.js的相关GitHub issue #708

Knockout 3.0的更新:

Knockout现在提供$rawData

<ul data-bind='foreach: list'>
    <li><input data-bind='value: $rawData'/></li>
</ul>

按预期创建双向绑定。

来自 Binding Context 文档:

  

$ RAWDATA

     

这是当前上下文中的原始视图模型值。通常这个   将与$ data相同,但如果视图模型提供给Knockout   包含在一个可观察的数据中,$ data将是未包装的视图模型,   和$ rawData本身就是可观察的。

答案 1 :(得分:6)

默认敲除绑定中使用的每个数据对象将始终被解包。因此,您基本上绑定到列表中项目的值,而不是您期望的可观察值。

Observables应该是对象的属性,而不是对象本身的替代。将observable设置为某个对象的属性,这样就不会发生。

​var vm = {
    list: [
        { value: ko.observable('123') },
        { value: ko.observable('456') }
    ]
};
<ul data-bind='foreach: list'>
    <li><input data-bind='value: value'/></li>
</ul>

<ul data-bind='foreach: list'>
    <li><span data-bind='text: value'></span></li>
</ul>