AngularJS - Route Life Cycle

The initial setup:

<div ng-app="app" ang-controller="AppCtrl">
  <ng-view></ng-view>
</div>
var app = angular.module('app', []);

app.config(function ($routeProvider, $locationProvider) {
  $routeProvider
    .when('/',
    {
      templateUrl: "app.html",
      controller: "ViewCtrl"
    }
    .when('/new',
    {
      templateUrl: "new.html",
      controller: "NewCtrl"
      resolve: {
        loadData: viewCtrl.loadData
      }
    }
  )
});

app.controller("AppCtrl", function ($rootScope) {
  $rootScope.$on("$routeChangeStart", 
                 function (event, current, previous, rejection) {
    console.log($scope, $rootScope, $route, $location);
  });      
  $rootScope.$on("$routeChangeSuccess", 
                 function (event, current, previous, rejection) {
    console.log($scope, $rootScope, $route, $location);
  });
});

var viewCtrl = app.controller("ViewCtrl", function ($scope, $route) {
  $scope.changeRoute = function () {
    console.log($scope);
    $location.path("/new");
  }
});

app.controller("NewCtrl", function($scope, loadData, $template) {
  console.log($scope, loadData, $template);
});

viewCtrl.loadData = function ($q, $timeout) {
  var defer = $q.defer;
  $timeout(function () {
    defer.resolve({message:"success"}); 
  }, 2000);
  return defer.promise;
};
<h1><a ng-click="changeRoute()">Change route</a></h1>
<h1>Hi, I'm new here!</h1>

Here, clicking on the <a> element in app.html triggers the changeRoute() method in the viewCtrl. That will change the location to /new, which will load the new.html template after the promises in that route have resolved. The promise waits 2 seconds and resolves with a message.

So, in order:

Before the route change begins, the click event invokes changeRoute().

var viewCtrl = app.controller("ViewCtrl", function ($scope, $route) {
  $scope.changeRoute = function () {
    console.log($scope);
    $location.path("/new");
  }
});

Before line 34 executes: Nothing has really happened yet - the path has not yet changed. Any work to be accomplished before the path changes must occur here.

Next, the route change has begun, the $routeChangeStart callback is invoked:

app.controller("AppCtrl", function ($rootScope) {
  $rootScope.$on("$routeChangeStart", 
                 function (event, current, previous, rejection) {
    console.log($scope, $rootScope, $route, $location);
  }); 

Before line 24 executes: Now, the path has changed. This is reached before any of the promises have been resolved. Current and previous objects are available for use. ‘previous’ additionally has an attribute object ‘locals’ which contains $template and $scope attributes. This is due to the fact that $routeChangeSuccess has not been reached yet, so the ‘current’ object has not received these yet.

Afterwards, the route change has successfully completed, and the $routeChangeSuccess callback is invoked:

  $rootScope.$on("$routeChangeSuccess", 
                 function (event, current, previous, rejection) {
    console.log($scope, $rootScope, $route, $location);
  }); 

Before line 28 executes: Now, examining the previous and current objects, we see that both have ‘locals’ attributes. The current.locals object will have a loadData object from the resolve() method, and also a $template object, with the parsed template from new.html. Angular is now ready to instantiate the new controller. The template has not yet rendered.

And finally, the NewCtrl is instantiated:

app.controller("NewCtrl", function($scope, loadData, $template) {
  console.log($scope, loadData, $template);
});

The controller is instantiated, and the scope is prepared. The view is about to render.