鉴于下面的场景,是否有必要使用ko.utils.domNodeDisposal.addDisposeCallback
取消绑定自定义绑定处理程序init中的click事件?或者Knockout是否有自己的机制来自动处理/解除在自定义绑定处理程序中创建的事件?
示例:
<li>
<a id='aTagId' data-bind='something'></a>
<button data-bind: myCustomBinding:{}>
</li>
ko.bindingHandlers.myCustomBinding=
{
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext)
{
$('#aTagId').on('click', function() { /*something in here*/ });
// Is this code necessary?
ko.utils.domNodeDisposal.addDisposeCallback(element, function ()
{
$('#aTagId').off('click');
});
}
}
注意:请不要问我为什么我不能将myCustomBinding
放在<a>
标记中:)
答案 0 :(得分:1)
我认为附加到长生活对象(window
,document
等)的事件处理程序是有意义的:
ko.bindingHandlers.myBinding = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var handler = function () {};
$(window).on("resize", handler);
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(window).off("resize", handler);
});
})
};
另见 - http://www.knockmeout.net/2014/10/knockout-cleaning-up.html
但在你的场景中
首先当您尝试拨打off
时,您的元素已被移除:
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$('#aTagId').off('click'); //<== $('#aTagId').length is 0
});
您可以按如下方式重写它:
var $aTag = $('#aTagId').on('click', function() {});
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$aTag.off('click');
});
但其次淘汰赛有自己的机制来自动处理/取消绑定事件。它正在运行jQuery.cleanData
// Perform cleanup needed by external libraries (currently only jQuery, but can be extended)
ko.utils.domNodeDisposal["cleanExternalData"](node);
...
"cleanExternalData" : function (node) {
// Special support for jQuery here because it's so commonly used.
// Many jQuery plugins (including jquery.tmpl) store data using jQuery's equivalent of domData
// so notify it to tear down any resources associated with the node & descendants here.
if (jQueryInstance && (typeof jQueryInstance['cleanData'] == "function"))
jQueryInstance['cleanData']([node]);
}
这样您的处理程序将自动处理