【问题标题】:Issues with Knockout nested bindings updating each other, but not the domKnockout 嵌套绑定的问题相互更新,但不是 dom
【发布时间】:2014-11-13 14:25:04
【问题描述】:

我有一个复合视图模型,其中包含其他视图模型,它引入了嵌套绑定。因此,一个嵌套子模型可能会更改另一个子模型的可观察对象,或者由其父模型拥有的对象。

following JsFiddle 上提供了一个示例

在那里,我正在修改一个可观察对象 (itemContainer),它本身公开了一个可观察数组属性 (items)。我希望能够在每次修改 items 属性或 itemContainer 本身时更改绑定。但是,两者似乎都对 dom 没有任何影响,而实际上绑定按预期发生 - 我正在使用 jQuery 修改跨度以在操作后断言元素的实际计数(请参阅“实际计数”值)。

所以,我创建了another JsFiddle,主要区别在于itemContainer 不再是可观察的属性。这次它几乎像我预期的那样工作。

但是,当我更改 itemContainer 或其 items 属性时,我需要能够自动更新 dom。我该怎么办?

此外,在这两种情况下,viewModel.actions.count 计算成员的绑定都不会重新评估。我将不胜感激任何关于它为什么不选择更改的见解。

【问题讨论】:

  • 您将如何更改项目容器?
  • @MatthewJamesDavis,一个可能的情况是在 reset 函数中,我设置了一个全新的对象:itemContainer({items: ko.observableArray(["item x", "item y"])});我使用的 JsFiddles 是我正在处理的“简化”场景,因此这些示例可能没有直接意义,但上面的 sn-p 是我想要解决的问题。此外,可以只改变 observable 数组——我的意思是我应该同时支持这两个
  • 如果对您有帮助,请不要忘记将答案标记为已接受

标签: javascript knockout.js nested


【解决方案1】:

在这里更新了工作小提琴:http://jsfiddle.net/hh233r3q/1/

问题出在您的模板中。你绑定 contents.itemContainer.items。

<!--ko foreach: contents.itemContainer.items -->

但是itemContainer被初始化为null,并且items不是null的属性。

itemContainer: ko.observable(null)

相反,您可以将 ko 与绑定一起使用。

<!-- ko with: contents.itemContainer -->
  <!-- ko foreach: items -->

带有绑定的 ko 会自动解开 itemContainer 并使用其中的模板(如果已定义)。见这里:http://knockoutjs.com/documentation/with-binding.html

另外,请注意,即使定义了 itemContainer,您仍然需要调用 observable 来获取底层对象。

<!--ko foreach: contents.itemContainer().items -->

【讨论】:

  • 谢谢,您和@TSV 的解决方案都对我有用。不过,我正忙于修复我正在从事的实际项目。
【解决方案2】:

这有帮助吗(jsfiddle)?

标记:

  <p id="target">
  <!--ko if: contents.itemContainer() -->
  <!--ko foreach: contents.itemContainer().items -->
    <!--ko template: 'itemTemplate', data: $data -->
    <!--/ko -->
  <!--/ko -->
  <!--/ko -->
   </p>
   <p id="actions">
      <button data-bind="click: actions.add">Add</button>
      <button data-bind="click: actions.reset">Reset</button>
    </p>
    <p>Databound count:<span data-bind="text: actions.count"></span></p>
    <p>Actual count:<span id="actualCount"></span></p>
    <script type="text/html" id="itemTemplate">
      <span data-bind="text: $data"></span>
    </script>

代码:

    var unwrap = ko.unwrap;
var viewModel = {
    contents: {
        itemContainer: ko.observable(null)
    },
    actions: {
        add: function () {
            if (!viewModel.contents.itemContainer()) {
                viewModel.contents.itemContainer({items: ko.observableArray([])});
            }
            if (viewModel.contents.itemContainer().items) {
                viewModel.contents.itemContainer().items.push("new item");
            }
            $("#actualCount").html(viewModel.contents.itemContainer().items().length);
        },
        reset: function () {
            viewModel.contents.itemContainer({items: ko.observableArray(["item 1", "item 2"])});
            $("#actualCount").html(viewModel.contents.itemContainer().items().length);
        },
        count: ko.computed(function() {
            if (!viewModel) {
                return -1;
            }
            return viewModel.contents.itemContainer().items().length;
        })
    }
};
ko.applyBindings(viewModel);

【讨论】:

    猜你喜欢
    • 2014-09-07
    • 2016-03-21
    • 2012-09-24
    • 2013-12-06
    • 1970-01-01
    • 2012-12-24
    • 2015-05-06
    • 2011-05-04
    • 1970-01-01
    相关资源
    最近更新 更多