如何在Knockout.js中清除/删除可观察的绑定?

2022-08-30 05:25:41

我正在将功能构建到用户可以多次执行的网页上。通过用户的操作,使用ko.applyBindings()创建一个对象/模型并将其应用于HTML。

数据绑定 HTML 是通过 jQuery 模板创建的。

目前为止,一切都好。

当我通过创建第二个对象/模型并调用ko.applyBindings()来重复此步骤时,我遇到了两个问题:

  1. 标记显示以前的对象/模型以及新的对象/模型。
  2. 与对象/模型中的某个属性相关的 javascript 错误会发生,尽管它仍在标记中呈现。

为了解决这个问题,在第一次传递之后,我调用jQuery的.empty()来删除包含所有数据绑定属性的模板化HTML,以便它不再在DOM中。当用户启动第二次传递的进程时,数据绑定 HTML 将重新添加到 DOM 中。

但就像我说的,当HTML被重新添加到DOM并重新绑定到新的对象/模型时,它仍然包含来自第一个对象/模型的数据,我仍然得到JS错误,这在第一次传递期间不会发生。

结论似乎是 Knockout 保留了这些绑定属性,即使标记已从 DOM 中删除。

因此,我正在寻找一种从Knockout中删除这些绑定属性的方法;告诉挖空不再有可观察的模型。有没有办法做到这一点?

编辑

基本过程是用户上传文件;然后,服务器使用 JSON 对象进行响应,将数据绑定 HTML 添加到 DOM,然后 JSON 对象模型使用

mn.AccountCreationModel = new AccountViewModel(jsonData.Account);
ko.applyBindings(mn.AccountCreationModel);

一旦用户对模型进行了一些选择,同一对象就会回发到服务器,数据绑定的HTML将从DOM中删除,然后我有以下JS

mn.AccountCreationModel = null;

当用户希望再次执行此操作时,将重复所有这些步骤。

恐怕代码太“复杂”了,无法进行jsFiddle演示。


答案 1

您是否尝试过在 DOM 元素上调用 knockout 的 clean node 方法来释放内存中绑定的对象?

var element = $('#elementId')[0]; 
ko.cleanNode(element);

然后,使用新的视图模型仅对该元素再次应用挖空绑定将更新视图绑定。


答案 2

对于我正在处理的项目,我编写了一个简单的函数,该函数接受jQuery节点和删除布尔值。它首先解绑所有jQuery事件,因为方法不处理这个问题。我已经测试了内存泄漏,它似乎工作得很好。ko.unapplyBindingsko.cleanNode

ko.unapplyBindings = function ($node, remove) {
    // unbind events
    $node.find("*").each(function () {
        $(this).unbind();
    });

    // Remove KO subscriptions and references
    if (remove) {
        ko.removeNode($node[0]);
    } else {
        ko.cleanNode($node[0]);
    }
};