Knockout's cleanNode()
function seems to be removing jQuery's event bindings on elements inside the node. How can I prevent this?
There is not much documentation I could find on cleanNode()
either.
问题:
回答1:
Directly from the knockout docs:
"Overriding the clean-up of external data
When removing an element, Knockout runs logic to clean up any data associated with the element. As part of this logic, Knockout calls jQuery’s cleanData method if jQuery is loaded in your page. In advanced scenarios, you may want to prevent or customize how this data is removed in your application. Knockout exposes a function, ko.utils.domNodeDisposal.cleanExternalData(node), that can be overridden to support custom logic. For example, to prevent cleanData from being called, an empty function could be used to replace the standard cleanExternalData implementation:"
ko.utils.domNodeDisposal.cleanExternalData = function () { // Do nothing. Now any jQuery data associated with elements will // not be cleaned up when the elements are removed from the DOM. };
Lately i went crazy because of endless debug sessions.
I saw this question, and I hope my answer gives a more immediate solution for those who are still searching.
回答2:
@T-moty answer is working fine, so i wrote a short function that override the cleanExternalData method, call clearNode and set original method back.
private koClearNode(element: HTMLElement) { var original = ko.utils.domNodeDisposal['cleanExternalData']; ko.utils.domNodeDisposal['cleanExternalData'] = function () { }; ko.cleanNode(element); ko.utils.domNodeDisposal['cleanExternalData'] = original; }
Also works in TypeScript, where cleanExternalData is not in typings.
回答3:
cleanNode does not take any parameters that would allow you to prevent this behavior. I think your best option would be to create your own method based off of the Knockout function but without the jQuery cleaning. Without having built a sample app to verify, I would look creating a function that is identical to cleanSingleNode(node) and remove this line:
if ((typeof jQuery == "function") && (typeof jQuery['cleanData'] == "function")) jQuery['cleanData']([node]);
You can check the debug source here to get more info on other related internal functions: http://knockoutjs.com/downloads/knockout-2.2.1.debug.js
回答4:
The best way to handle this is to keep the jQuery bindings code separate from the knockout bindings. In this way, you can simply call the function to redo the jQuery bindings. Unfortunately, a code refactor of existing code might be required to do this.