2016-11-06 67 views
1

鑑於下面的情況,有必要使用ko.utils.domNodeDisposal.addDisposeCallback來解除綁定自定義綁定處理程序init內部的單擊事件?或者Knockout有它自己的機制來自動處理/解除在自定義綁定處理程序中創建的事件?是否有必要在Knockout自定義綁定中解除綁定/關閉JQuery點擊事件?

例子:

<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

我想這是有道理的,附着於長期的事件處理程序生命的物體(windowdocument等):

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

https://github.com/knockout/knockout/blob/241c26ca82e6e4b3eaee39e3dc0a92f85bc1df0c/src/utils.domNodeDisposal.js#L88-L94

這樣你的處理程序會自動配置

enter image description here

+0

這個答案道理給我。我試圖在addDisposeCallback中找到click事件,但即使''標籤仍然存在,也找不到該事件。謝謝! – jtabuloc