Memory leaks in Angular.JS directives
A bit of action!
What we should do when scope has to die
Directives - release DOM trees
First arrest
- Release any reference to detached DOM trees
- Use scope $destroy event, prior to scope destruction
return function alCaponeLink(scope, element, attrs) {
(function perform100Robberies() {
var div,
i;
for(i = 0; i < 1000; i+=1) {
div = $window.document.createElement('div');
$window.alCaponeTreasure.push(div);
}
})();
scope.$on('$destroy', function findCaponeTreasure() {
$window.alCaponeTreasure = null; // <- This fixes the leak
});
};
Directives - destroy third party plugins
Second arrest
- Use plugin API to remove/destroy plugin
- Fixed jQueryUI bug - datepicker_instActive
function timeBombDirective () {
return function timeBombLnk(scope, element, attrs) {
(function setTimeBomb() {
element.datepicker();
})();
scope.$on('$destroy', function neutralizeTimeBomb() {
element.datepicker('destroy'); // <- This fixes the leak
});
};
}
Directives - stop any running interval
Third arrest
- Release
setInterval
on $destroy event
- Manual destruction of the interval still needed with $interval
function tedBundyDirective ($interval) {
var Body = function () {
// define person
};
return function tedBundyLink(scope, element, attrs) {
var bodies = [],
killingInterval = $interval(function kill() {
bodies.push(new Body());
}, 50);
scope.$on('$destroy', function arrestTedBundy() {
$interval.cancel(killingInterval); // <- This fixes the leak
})
};
}