我有一个类似数据的模态弹出窗口,需要清除绑定。 The answer for the highest rating说要使用knockout的清洁节点方法
以下是(手写)代码段:
var ViewModel = function(v) {
var self = this;
self.Foo = ko.observable(v.Foo);
self.Bar = ko.observable(v.Bar);
self.Stuffs = ko.observableArray([]);
self.AddStuffs = function() { ... }
}
var myViewModel = new ViewModel({Foo : "", Bar: "" });
var myModal= document.getElementById("myModal");
ko.cleanNode(myModal);
ko.applyBindings(myViewModel, myModal);
HTML:
<div id="myModal">
<a href="#" data-bind="click:$root.AddStuff">my link</a>
<table>
<tbody data-bind="foreach:Stuffs ">
<tr>
<td><span data-bind="text:Interval"></span></td>
</tr>
</tbody>
</table>
</div>
当我第一次打开模态时,一切似乎都正常。但是this answer说cleanNode是错误的解决方案,因为cleanNode是淘汰的内部清理。它不会清理事件处理程序,因此当我的模态关闭并再次打开并单击AddStuff的链接时,该事件将被调用n次(n =我打开弹出窗口的次数)。提到的解决方案是“更好的模式是使用或围绕一个部分使用模板绑定,并允许使用新绑定重新渲染它。”但是没有关于如何做的任何后续行动。
我不确定“模板”是什么意思,但我tried adding "with"绑定我用于模态的div,并且在一次链接点击时仍然会多次调用事件。有人可以帮我找到一种让这种方法正常工作的方法吗?
答案 0 :(得分:1)
我不认为cleanNode
是你想要的。一般来说,你不应该清理节点并重新应用绑定,除非你做了一些非常不寻常的事情,我不认为你是这样。您只是想更改DOM的特定部分绑定的ViewModel,对吗?
我只需要创建一个可观察的视图,该视图保存模式应绑定到的ViewModel,然后根据该模板编写模板。
var ModalViewModel = function(v) {
var self = this;
self.Foo = ko.observable(v.Foo);
self.Bar = ko.observable(v.Bar);
self.Stuffs = ko.observableArray([]);
self.AddStuffs = function() { ... }
}
var modalViewModel = new ModalViewModel({Foo : "Foo", Bar: "Bar" });
var viewModel = {
modal: ko.observable(modalViewModel)
};
var myModal= document.getElementById("myModal");
ko.applyBindings(myViewModel, myModal);
请注意,实际绑定到模式的viewModel永远不会更改,但包含一个子视图模型。上述逻辑应该只执行一次,然后更改或删除模态,可以修改viewModel.modal
observable。
然后你的模板看起来像
<div id="myModal" data-bind="with: modal">
<a href="#" data-bind="click:AddStuff">my link</a>
<table>
<tbody data-bind="foreach:Stuffs ">
<tr>
<td><span data-bind="text:Interval"></span></td>
</tr>
</tbody>
</table>
</div>
(唯一的变化是with: modal
部分,删除了不必要的$root
)
这是一个展示此工作的简约版本:http://jsfiddle.net/260wypyk/