Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to destroy an angularjs app?

Tags:

angularjs

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?

like image 534
CHS Avatar asked Feb 20 '13 21:02

CHS


2 Answers

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');
like image 82
Kloe2378231 Avatar answered Oct 04 '22 00:10

Kloe2378231


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;
        }
}
like image 43
Johannes Jander Avatar answered Oct 04 '22 00:10

Johannes Jander