What is the lifecycle of an AngularJS Controller?

JavascriptAngularjs

Javascript Problem Overview


Can someone please clarify what the lifecycle of an AngularJS controller is?

  • Is a controller a singleton, or created / destroyed on demand?
  • If the latter, what triggers the creation / destruction of the controller?

Consider the below example:

var demoApp = angular.module('demo')
  .config(function($routeProvider, $locationProvider) {
    $routeProvider
      .when('/home', {templateUrl: '/home.html', controller: 'HomeCtrl'})
      .when('/users',{templateUrl: '/users.html', controller: 'UsersCtrl'})
      .when('/users/:userId', {templateUrl: '/userEditor.html', controller: 'UserEditorCtrl'});
  });

demoApp.controller('UserEditorCtrl', function($scope, $routeParams, UserResource) {
  $scope.user = UserResource.get({id: $routeParams.userId});
});

eg:

In the above example, when I navigate to /users/1,user 1 is loaded, and set to the $scope.

Then, when I navigate to /users/2, user 2 is loaded. Is the same instance of UserEditorCtrl reused, or is a new instance created?

  • If it's a new instance, what triggers the destruction of the first instance?
  • If it's reused, how does this work? (ie., the method to load the data appears to run on creation of the controller)

Javascript Solutions


Solution 1 - Javascript

Well, actually the question is what is the life cycle for a ngView controller.

Controllers are not singletons. Anyone can create a new controller and they are never auto-destroyed. The fact is that it's generally bound to the life cycle of its underlying scope. The controller is not automatically destroyed whenever its scope is destroyed. However, after destroying an underlying scope, its controller is useless (at least, by design, it should be).

Answering your specific question, a ngView directive (as well for ngController directive) will always create a new controller and a new scope every time a navigation happens. And the last scope is going to be destroyed as well.

The life cycle "events" are quite simple. Your "creation event" is the construction of your controller itself. Just run your code. To know when it gets useless ("destruction event"), listen to scope $destroy event:

$scope.$on('$destroy', function iVeBeenDismissed() {
  // say goodbye to your controller here
  // release resources, cancel request...
})

For ngView specifically, you are able to know when the content gets loaded through the scope event $viewContentLoaded:

$scope.$on('$viewContentLoaded', function readyToTrick() {
  // say hello to your new content here
  // BUT NEVER TOUCHES THE DOM FROM A CONTROLLER
});

Here is a Plunker with a concept proof (open your console window).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarty PittView Question on Stackoverflow
Solution 1 - JavascriptCaio CunhaView Answer on Stackoverflow