我试图了解我在使用 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 会为你处理所有这些。
关于javascript - Knockoutjs ObservableArray 的大小不断翻倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13410338/