Yes, in fact there is, and it's kind of easy to miss because it isn't documented very well.
Knockout has a utility function ko.utils.domNodeDisposal.addDisposeCallback(element, callback)
. This function makes sure the callback is invoked when the element is disposed of. However, 'disposed of' is very specific in this case. jQuery.remove()
won't trigger it. The way to dispose of the node is to use ko.removeNode(element)
, which not only removes the DOM element (and its children), but also does some extra cleanup in terms of bound event handlers and such. (I'm sorry, the details are a bit hazy. You can always check Knockout's implementation if you want more detail on this.)
Internally, when disposing of a view, Durandal uses ko.removeNode
. Therefore, when a view is removed, all elements are removed as well and any disposeCallbacks set up using the aforementioned utility function will be invoked. I'm fairly sure that Durandal hooks into this process to trigger the callback for deactivate.
TL;DR: try ko.removeNode(element)
instead of jQuery.remove(element)
. That will trigger your deactivate callback.