Reputation: 2535
Given the scenario below is it necessary to unbind click event inside custom binding handler init using ko.utils.domNodeDisposal.addDisposeCallback
? Or does Knockout has it's own mechanism to automatically dispose/unbind event created inside custom binding handler?
Example :
<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');
});
}
}
Note : Please don't ask me why I can't just put myCustomBinding
in <a>
tag :)
Upvotes: 1
Views: 315
Reputation: 214007
I guess it makes sense for event handlers attached to long-living objects(window
, document
etc):
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);
});
})
};
See also - http://www.knockmeout.net/2014/10/knockout-cleaning-up.html
But in your scenario
Firstly your element is already removed when you're trying to call off
:
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$('#aTagId').off('click'); //<== $('#aTagId').length is 0
});
You can rewrite it as follows:
var $aTag = $('#aTagId').on('click', function() {});
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$aTag.off('click');
});
But secondly knockout has it's own mechanism to automatically dispose/unbind event. It's running 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]);
}
This way your handler will be automatically disposed
Upvotes: 0