Ran across a very "down-the-rabbit-hole" Angular question today I couldn't find the answer to. From the $scope
docs, you can register an event handler on "$destroy"
, which is called right before a scope's destruction. That way, you can deregister event handlers like so:
var deregister = $scope.$on('myCustomEvent', function () {
// do some crazy stuff
});
$scope.$on('$destroy', function () {
deregister();
});
However, the $scope.$on('$destroy', ...)
must create its own handler. Is that automatically destroyed, or do you have to do something like the following to destroy it?
var deregister = $scope.$on('myCustomEvent', function () {
// do some crazy stuff
});
var deregisterDestroy = $scope.$on('$destroy', function () {
deregister();
deregisterDestroy();
});
The answer is actually "maybe" depending on what you mean by it being automatically destroyed. If we look at the source for the $destroy
method for scopes, we can see that while a $destroy
event is broadcasted downward throughout child scopes, the actual $destroy
method is never invoked on any scope but the initial one. That means that the actual cleanup and nulling out of properties never occurs on child scopes.
The reason that this doesn't leak memory is because once $destroy
has been invoked on a scope, it becomes detached from the parent scope and is therefore eligible for garbage collection since it should no longer have any path to the GC Roots. This same logic applies to all child scopes since they also should have no paths to the GC Roots.
Your example is safe though; I do that myself in the same manner to clean up my own handlers when necessary and do not run into any kind of infinite loops.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With