这是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 回答
默认敲除绑定中使用的每个数据对象将始终被解包 . 因此,您基本上绑定到列表中项目的值,而不是您期望的可观察值 .
Observable应该是对象的属性,而不是对象本身的替代 . 将observable设置为某个对象的属性,这样就不会发生 .
我使用
value: $parent.list[$index()]
解决了这个问题,如this jsFiddle所示 . 新绑定看起来像这样:人们可以通过自定义绑定来改进这一点 .
另请参阅与Knockout.js相关的GitHub issue #708 .
Update for Knockout 3.0:
Knockout现在提供
$rawData
:按预期创建双向绑定 .
来自Binding Context文档: