No, you do not need to delete $$watchers , as they will be effectively deleted after the destruction of the area.
From Angular source code (v1.2.21), Scope $destroy method:
$destroy: function() { ... if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling; if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling; if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling; if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling; ... this.$$watchers = this.$$asyncQueue = this.$$postDigestQueue = []; ...
So, the $$watchers array is omitted (and the region is removed from the region hierarchy).
Retrieving watcher from an array is all an unregistered function:
$watch: function(watchExp, listener, objectEquality) { ... return function deregisterWatch() { arrayRemove(array, watcher); lastDirtyWatch = null; }; }
So, it makes no sense to unregister $$watchers manually.
You should still unregister event listeners (as you correctly noted in your message)!
Note: You only need to unregister listeners registered in other areas. There is no need to unregister listeners registered in an area that is being destroyed.
For example:.
// You MUST unregister these $rootScope.$on(...); $scope.$parent.$on(...); // You DON'T HAVE to unregister this $scope.$on(...)
(thanks to @John for pointing this out )
Also, make sure you unregister any event listeners from elements that survive the destructible region. For example. if you have a directive, register the listener on the parent node or on <body> , then you must also unregister.
Again, you do not need to delete the listener registered on the element to be destroyed.
The view is not related to the original question, but now there is also the $destroyed event dispatched to the element to be destroyed, so you can also connect to it (if it suits your usecase):
link: function postLink(scope, elem) { doStuff(); elem.on('$destroy', cleanUp); }