Knockout.js cleanNode是否会删除所有关联的事件侦听器? [英] Does knockout.js cleanNode remove all associated event listeners?

查看:71
本文介绍了Knockout.js cleanNode是否会删除所有关联的事件侦听器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过ajax加载页面,在每个ajax请求开始时,我都会清理页面,然后在添加的新页面上加载applybindings.我始终保持一个持久的模型,这是不断更新的视图.

I'm loading pages via ajax, on the start of each ajax request I clean the page and then load applybindings on the new page that is added. I keep a persistent model throughout, it's the view that updates.

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);
}

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

My problem is that in cleaning the node, I seem to be erasing the event listener attached to my anchor link on the page. This anchor link contains an element displays a counter of products in my model

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

我在其他地方设置的事件不再触发,我的页面刷新,而不是运行ajax调用.

This event I have setup elsewhere no longer gets triggered, my page refreshes instead of running the ajax call.

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();
        }
    });
}

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

Is there a better way to go about this? Does cleaning the node remove all associated event listeners?

推荐答案

首先,您发现您不应使用cleanNode .

First, as you found, you should not use cleanNode.

第二,您应该更喜欢让Knockout管理整个DOM,而不是其中的一部分.在您的情况下,您将以老式的方式自行处理该应用程序,并使用Knockout管理更改的内容.

Second, you should prefer to have Knockout manage the entire DOM rather than a chunk of it. In your case, you're handling the app the old-fashioned manipulate-the-DOM-yourself way, and managing the changing content with Knockout.

您真正需要的是 html绑定的版本它的内容.使用 applyBindingsToDescendants 的简单自定义绑定处理程序可以使工作.示例:

All you really need is a version of the html binding that applies bindings to its content. A simple custom binding handler using applyBindingsToDescendants can make that work. Example:

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>

这篇关于Knockout.js cleanNode是否会删除所有关联的事件侦听器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆