Viv*_*vek 1 html javascript knockout.js knockout-3.0
我有一个自定义的 KO 组件地址输入
ko.components.register('address-input', {
viewModel: { createViewModel: function ({}, componentInfo) {
var self = {};
self.dispose = function() {
// When removed by KO, dispose computeds and subscriptions
};
return self;
}},
template: 'address-input'
});
Run Code Online (Sandbox Code Playgroud)
对应的模板是address-input.html
<div class`enter code here`="clearfix row">
<!-- elements come here -->
</div>
Run Code Online (Sandbox Code Playgroud)
我的应用程序是一个 SPA 应用程序,其基本布局如下所示
一个main.html中会包含section.html这inturn持有地址输入,HTML。在页面 nav 上,section.html将被另一个 html 替换,依此类推。
部分 htmls 通过 AJAX 加载
$j.ajax({
url: url,
success: function(htmlText) {
var $el = $j(element);
$el.html(htmlText);
ko.applyBindingsToDescendants(bindingContext, $el[0]);
},
cache: false,
mimeType: 'text/html-ko'
});
Run Code Online (Sandbox Code Playgroud)
将来我可能会在地址输入组件中订阅一些 observable。发生这种情况时,我希望在离开页面时调用 dispose 方法。但现在没有发生。这里有什么问题?这是 DOM 没有从内存中删除的情况吗?如果是这样,为什么?
您正在使用 jQuery 替换 DOM 树的一部分。Knockout 无法知道删除了哪些元素,也无法调用dispose绑定模型。
用淘汰赛的html结合添加/删除新的部分或(不推荐)调用ko.cleanNode(element)之前调用$el.html。
一个例子显示:
disposeforeach, if, with)时,敲除会dispose在必须删除内容时调用ko.cleanNode,knockout 会将所有节点从它们的模型中分离出来,调用dispose,然后让您对剩余的 DOM 节点执行您想要的操作。ko.components.register('mycomponent', {
viewModel: function(params) {
this.dispose = () => console.log("Dispose called");
},
template: "<li>My Component</li>"
});
// Some example data to render a list
const comps = ko.observableArray([1, 2, 3, 4]);
// Remove straigt from the DOM without knockout...
const badRemove = () => document
.querySelector("mycomponent:last-child")
.remove();
const manualDetach = () => ko.cleanNode(document.querySelector("div"));
// Use knockout to alter the DOM
const goodRemove = () => comps.shift();
ko.applyBindings({ comps, badRemove, goodRemove, manualDetach });Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="foreach: comps">
<mycomponent></mycomponent>
</div>
<button data-bind="click: badRemove">bad remove</button>
<button data-bind="click: goodRemove">good remove</button>
<button data-bind="click: manualDetach">clean node</button>Run Code Online (Sandbox Code Playgroud)