javascript - Knockoutjs ObservableArray 的大小不断翻倍

标签 javascript knockout.js

我试图了解我在使用 KnockoutJS 制作的页面中看到的一些稍微奇怪的行为。每次我清除并重新应用绑定(bind)时,可观察数组似乎都会得到重复项。了解问题的最快方法是查看此 JSFiddle demo .只需点击任意编辑按钮数次,即可看到此列表不断增长!

此演示代码的核心是以下方法:

var _bindItemDetail = function (jsonData) {
        //clear existing bindings
        ko.cleanNode($("#itemdetails").get(0));

        // observables in selected item.
        _viewModel.SelectedItem(ko.mapping.fromJS(jsonData));

        // Apply Bindings
        ko.applyBindings(_viewModel.SelectedItem, $("#itemdetails").get(0));
    };

我想要实现的本质是将列表和详细信息页面合二为一。列表 JSON 在初始页面加载时获取,详细 JSON 在单击编辑链接时获取并绑定(bind)到“详细信息”html。

除了解决问题之外,我还试图了解行为,并吸取一些关于如何在使用 knockout 时正确清理陈旧资源的经验教训。

感谢您的帮助

最佳答案

问题在于,在您的 _bindItemDetail 函数中,您正在对已复制元素的修改后的 View 重新应用绑定(bind)。

var _bindItemDetail = function (jsonData) {
    //clear existing bindings
    ko.cleanNode($("#itemdetails").get(0));

    // observables in selected item.
    _viewModel.SelectedItem(ko.mapping.fromJS(jsonData));

    // Apply Bindings
    ko.applyBindings(_viewModel.SelectedItem, $("#itemdetails").get(0));
};

ko.cleanNode() 只是从元素中移除绑定(bind),它不会将 View 恢复到其初始状态。通常,您应该只在一组节点上调用一次 ko.applyBindings。多做几次,就是自找麻烦。

坦率地说,您并没有很好地利用击倒。您的大部分代码都使用 jquery 来处理所有低级细节。使用 knockout 的目的是不必担心那些较低级别的细节。

我对您的 fiddle 做了一些调整,以便更好地使用 knockout,而不是那么强调使用 jquery。

在 View 中:

  • 使用 click 绑定(bind)来处理您的 Edit 点击事件。
  • 使用 with 绑定(bind)有条件地显示编辑器字段。不需要 stopBindings 处理程序。

在 View 模型中:

  • 将点击处理程序 editClicked 添加到 View 模型。
  • 删除了 jquery 事件绑定(bind)。
  • 删除了绑定(bind)项目时的 ko.cleanNode/ko.applyBindings 组合。你不应该那样做,你只是不需要它,knockout 会为你处理所有这些。

Updated fiddle

关于javascript - Knockoutjs ObservableArray 的大小不断翻倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13410338/

相关文章:

javascript - knockoutJS $index 无法正常工作

javascript - 如何通过多个条件过滤数组但保持其当前状态?

javascript - 我不能使用 val()?

javascript - 构建基本的 javascript 对象数组

javascript - knockout JS : Dynamic tabs with dynamic content

javascript - Knockout、Require、Sammy 和每个页面的 View 模型——如何让它工作?

javascript - jQuery 更改不会在 IE 中从扩展选择中触发

JavaScript 向对象添加隐藏数据

selenium - FindElement 不返回元素文本,除非实际上在 DOM 中

javascript - 使用 jQote2 的 knockout 模板