I have an Angular directive that sets an element\'s height equal to the inner height of the browser window (+/- a given offset). This directive responds to the window\'s \"r
Pass the same function reference to off
as you pass to on
:
window.angular.element($window).off('resize', onResize);
Instead of:
window.angular.element($window).off('resize');
Demo - Passing function reference to off: http://plnkr.co/edit/1rfVPNXl6TrEcuYvzPAj?p=preview
Demo - Not passing function reference to off: http://plnkr.co/edit/IsLqSLAzNcHqDnhMty7Q?p=preview
The demos contain two directives both listening to the window resize event. Use the vertical separator between the code and the preview to trigger the event.
You will notice that if you destroy one the other will keep working when passing function reference to off. If you don't, both will stop working.
I had the same question a few weeks ago.
After looking through the jqLite source (https://github.com/angular/angular.js/blob/master/src/jqLite.js), we see that the on
method adds the event and the off
method removes the event via the jqLiteOff
function.
Looking deeper, we see jqLiteRemoveData
calls jqLiteOff
. jqLiteRemoveData
is called by jqLiteDealoc
. jqLiteDealoc
gets called in a few places: jqLiteEmpty
, html
, replaceWith
, and remove
. jqLiteEmpty
gets assigned to the element's empty
method, which clears the element in jQuery. html
, replaceWith
and remove
are jQuery mimics.
Doing a search on where remove()
is called on an element, we see that it is used on most, if not all, DOM manipulation logic. You can see it in ngIf
, ngSwitch
, ngInclude
and ngView
.
So I think Angular does handle event listener cleanup, as long as you use jqLite to attach events and call remove()
appropriately in your own DOM manipulation logic. Using jQuery to wrap an element would mess up a lot of processes, including event listener cleanup, but I guess you are already fully aware of that since you are using angular.element
.
For one, there is absolutely nothing wrong with using JQuery and AngularJS together.
That aside, what I like to do is have a body
directive which listens to window.on('resize', ...)
and writes the size into $rootScope.windowSize
. Then have another directive on the element, to $watch("windowSize", ...)
and set to width as needed. (You don't actually have to expose the size in $scope
- you can instead use require
).