I need to be able to load/unload angular applications dynamically without causing memory leaks. In jQuery you can do $("#elementHoldingMyWidget").remove();
and the proper destruction code gets executed, event handlers are unbound etc.
I've been unable to find anything in the angular docs mentioning the possibility of tearing down an app once it's been bootstrapped.
My 1st attempt was to destroy the rootScope like so:
var rootScope = $("body").scope();
rootScope.$destroy();
But this doesn't seem to be working, and I'm not sure how the injector and services would be cleaned up even if it did.
How should this be done?
Using AngularJS 1.4.0, $rootScope.$destroy() is working again (as it was broken in 1.2). Using this permits to switch between several angularJS apps:
var appManager = new function () {
this.currentAppName;
this.currentApp;
this.startApp = function (appContainerId, appName) {
if (this.currentApp) {
this.destroyApp(this.currentApp, this.currentAppName);
}
var appContainer = document.getElementById(appContainerId);
if (appContainer) {
this.currentAppName = appName;
this.currentApp = angular.bootstrap(appContainer, [appName]);
}
}
this.destroyApp = function (app, appName) {
var $rootScope = app.get('$rootScope');
$rootScope.$destroy();
}
}
// Call this when page is ready to rebootsrap app
appManager.startApp('divContainerId', 'app');
To tear down my application without presenting the user with a white page via $('body').empty
, I first $delete()
the child scopes and then remove all the properties from $rootScope
:
/*
* Iterate through the child scopes and kill 'em
* all, because Angular 1.2 won't let us $destroy()
* the $rootScope
*/
var scope = $rootScope.$$childHead;
while (scope) {
var nextScope = scope.$$nextSibling;
scope.$destroy();
scope = nextScope;
}
/*
* Iterate the properties of the $rootScope and delete
* any that possibly were set by us but leave the
* Angular-internal properties and functions intact so we
* can re-use the application.
*/
for(var prop in $rootScope){
if (($rootScope[prop])
&& (prop.indexOf('$$') != 0)
&& (typeof($rootScope[prop]) === 'object')) {
$rootScope[prop] = null;
}
}
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