Knockout.js的cleanNode不会解绑事件

Knockout.js's cleanNode does not unbind events

本文关键字:事件 js cleanNode Knockout      更新时间:2023-09-26

我有一个具有类似数据的模态弹出窗口,需要清除绑定。最高评级的答案说使用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>

当我第一次打开模态时,一切似乎都正常。但是这个答案说cleanNode是不正确的解决方案,因为cleanNode是敲除的内部清理。它不会清理事件处理程序,因此当我的模式关闭并再次打开并且我单击 AddStuff 的链接时,该事件被调用 n 次(n = 我打开弹出窗口的次数(。提到的建议解决方案是"更好的模式是使用或模板绑定围绕一个部分,并允许它使用新的绑定重新呈现",但没有关于如何做的后续行动。

我不确定他所说的"模板"是什么意思,但我尝试添加"with"来绑定我用于模态的div,并且一次链接单击仍然多次调用事件。有人可以帮助我找到一种方法来正确工作吗?

我不认为cleanNode是你想要的。 一般来说,你不需要清理节点和重新应用绑定,除非你正在做一些非常不寻常的事情,我认为你不是。 您只想更改 DOM 的特定部分绑定到的视图模型,对吗?

我只是制作一个可观察量,其中包含模态应绑定到的 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

然后你的模板看起来像

<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/