12

这是一个 jsFiddle演示以下问题:

给定(可观察的)字符串列表上的 foreach 绑定,可观察对象似乎不会从绑定在 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);​

在上面的例子中,人们会期望更新第一个列表中的输入标签会导致 observables 更新。不幸的是,它们没有按预期更新,从第二个列表未能反映对第一个列表所做的任何更改可以看出。

我验证了当输入元素发生变化时,列表实际上并没有被更新。有趣的是,对可观察对象所做的更改都反映在两个列表中(正如人们所期望的那样)。即,vm.list[1]("444")将更新两个列表的第二个元素。

我的回忆是 Knockout 2.0.0 没有这个问题,尽管我有待纠正。我没有在 Knockout 代码中找到任何文档、Google 或注释来说明为什么这不起作用或如何实现预期的结果。

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

4

2 回答 2

16

value: $parent.list[$index()]正如在这个 jsFiddle中看到的那样,我通过使用来解决这个问题。新绑定如下所示:

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

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

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

淘汰赛 3.0 更新:

淘汰赛现在提供$rawData

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

按预期创建双向绑定。

绑定上下文文档:

$原始数据

这是当前上下文中的原始视图模型值。通常这将与 $data 相同,但如果提供给 Knockout 的视图模型包装在可观察对象中,则 $data 将是未包装的视图模型,而 $rawData 将是可观察对象本身。

于 2012-11-12T20:37:50.187 回答
6

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

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

​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>
于 2012-11-12T19:59:31.867 回答