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>