首页 文章

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

提问于
浏览
12

这是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 回答

  • 6

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

    Observable应该是对象的属性,而不是对象本身的替代 . 将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>
    
  • 14

    我使用 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 .

    Update for Knockout 3.0:

    Knockout现在提供 $rawData

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

    按预期创建双向绑定 .

    来自Binding Context文档:

    $ rawData这是当前上下文中的原始视图模型值 . 通常这与$ data相同,但是如果提供给Knockout的视图模型包含在一个observable中,$ data将是展开的视图模型,$ rawData将是observable本身 .

相关问题