javascript - knockout.js cleanNode 是否删除所有关联的事件监听器?

标签 javascript knockout.js

我通过 ajax 加载页面,在每个 ajax 请求开始时我清理页面,然后在添加的新页面上加载 applybindings。我始终保持持久模型,更新的是 View 。

addEventListeners(){
    this.subscriptions.push(PubSub.subscribe('route.start',  this.removeShopView));
    this.subscriptions.push(PubSub.subscribe('route.success',  this.addShopView));
}

removeShopView(){
    ko.cleanNode(this.currentPage);
}   

addShopView(){
    this.currentPage = document.querySelector('.page-context');
    ko.applyBindings(this.model, this.currentPage);
}

我的问题是,在清理节点时,我似乎正在删除附加到页面上我的 anchor 链接的事件监听器。此 anchor 链接包含一个元素,显示我模型中的产品计数器

<ul>
    <li><a class='nav-bag' href="/bag">Bag<span data-bind='text: counter'></span></a></li>
</ul>

我在别处设置的这个事件不再被触发,我的页面刷新而不是运行 ajax 调用。

setupLinks(){
    this.pageContextWrap.addEventListener("click", (e) => {
        this.linkClickType = undefined;
        if (e.target && e.target.nodeName.toLowerCase() == 'a') {

            if(href.indexOf(document.domain) === -1) {
                console.log("outside link");
                this.href = false;
                return;
            }

            // anchor link is local page, ajax load the href
            this.doAjaxCall();
            e.preventDefault();
            e.stopPropagation();
        }
    });
}

有没有更好的方法来解决这个问题?清理节点是否会删除所有关联的事件监听器?

最佳答案

首先,如您所见,you should not use cleanNode .

其次,您应该更愿意让 Knockout 管理整个 DOM 而不是其中的一部分。在您的情况下,您正在以老式的自己操作 DOM 的方式处理应用程序,并使用 Knockout 管理不断变化的内容。

您真正需要的是 html binding 的一个版本将绑定(bind)应用于其内容。使用 applyBindingsToDescendants 的简单自定义绑定(bind)处理程序可以做到这一点。示例:

ko.bindingHandlers.boundHtml = {
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        const contentHtml = ko.unwrap(valueAccessor());
        
        element.innerHTML = contentHtml;
        ko.applyBindingsToDescendants(bindingContext, element)
    }
};

const someContents = [
'First content <span data-bind="text:someValue"></span>',
'Second content <span data-bind="text:anotherValue"></span>',
'Third content <span data-bind="text:someValue() + anotherValue()"></span>'
]

ko.applyBindings({
  pageContent: ko.observable('hi there'),
  someValue: ko.observable(3),
  anotherValue: ko.observable('foo'),
  changePage() {
    if (someContents.length) {
      this.pageContent(someContents.shift());
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="boundHtml:pageContent"></div>
<button data-bind="click:changePage">Change</button>

关于javascript - knockout.js cleanNode 是否删除所有关联的事件监听器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43482073/

相关文章:

JavaScript-MVC.NET : Get value of Multimensional Array

javascript - 如何在 JavaScript 文件中允许空格?

javascript - 配置加载更多按钮

javascript - 在多个绑定(bind)的 KnockoutJs 订阅函数中完成相同的任务

javascript - 使用 .NET Web 服务开发纯 HTML+JS 应用程序是否可行且安全?

javascript - 变换方法中的 Raphael 标度中心

javascript - 如何从嵌入的 pdf 到浏览器进行通信

javascript - Knockoutjs 无法解析绑定(bind)。消息: SyntaxError: Unexpected token };

javascript - 基于函数的 View 模型未转换为 JSON

knockout.js - 使用 KnockoutJS 映射插件执行部分更新