AngularJS: lazy loading controllers and content AngularJS: lazy loading controllers and content javascript javascript

AngularJS: lazy loading controllers and content


You can also use the jquery with the resolve the $routeProvider

app.js

/* Module Creation */var app = angular.module ('app', ['ngRoute']);app.config(['$routeProvider', '$controllerProvider', function($routeProvider, $controllerProvider){/*Creating a more synthesized form of service of $ controllerProvider.register*/app.registerCtrl = $controllerProvider.register;function loadScript(path) {  var result = $.Deferred(),  script = document.createElement("script");  script.async = "async";  script.type = "text/javascript";  script.src = path;  script.onload = script.onreadystatechange = function (_, isAbort) {      if (!script.readyState || /loaded|complete/.test(script.readyState)) {         if (isAbort)             result.reject();         else            result.resolve();    }  };  script.onerror = function () { result.reject(); };  document.querySelector("head").appendChild(script);  return result.promise();}function loader(arrayName){    return {      load: function($q){                var deferred = $q.defer(),                map = arrayName.map(function(name) {                    return loadScript('js/controllers/'+name+".js");                });                $q.all(map).then(function(r){                    deferred.resolve();                });                return deferred.promise;        }    };}$routeProvider      .when('/', {        templateUrl: 'views/foo.html',        resolve: loader(['foo'])    })    .when('/bar',{        templateUrl: 'views/bar.html',        controller: 'BarCtrl',        resolve: loader(['bar'])    })    .otherwise({        redirectTo: document.location.pathname    });}]);

/views/foo.html

<section ng-controller='FooCtrl'>    {{text}}</section>

js/controllers/foo.js

/*Here we use the synthesized version of $controllerProvider.register to register the controller in view*/app.registerCtrl('FooCtrl',function($scope){    $scope.text = 'Test';});

/views/bar.html

<section>    {{text2}}</section>

js/controllers/bar.js

app.registerCtrl('BarCtrl',function($scope){    $scope.text2 = 'Test';});


////JConfig file--------

window.angularApp.config(function ($routeProvider,$controllerProvider,$compileProvider,$provide, azMessages) {$routeProvider.when('/login', {             resolve: {                 load: ['$q', '$rootScope', function ($q, $rootScope) {                     var deferred = $q.defer();                     require([                         //load required Js file here                ], function () {                    $rootScope.$apply(function () {                        deferred.resolve();                    });                });                     return deferred.promise;                 } ]             }         });  $routeProvider.otherwise({ redirectTo: '/login' });    window.angularApp.components = {        controller: $controllerProvider.register,        service: $provide.service,        directive: $compileProvider.directive    }

//contoller declaration

angularApp.components.controller('DiscussionController',[function(){}]);


At first I utilized André Betiolo's answer. However, it does not always work becasue the ajax loading is non-blocking causing the view to sometimes request the controller prior to the script being loaded.

As a solution i forced the function not to return until all scripts successfully loaded. This is kind of hackish but makes sure the loads are successful prior to completing the resolve. It also allows for loading of multiple controllers.

app.js

var app = angular.module ('app', ['ngRoute']);app.config(['$routeProvider', '$controllerProvider', function($routeProvider, $controllerProvider){    /*Creating a more synthesized form of service of $ controllerProvider.register*/    app.registerCtrl = $controllerProvider.register;    //jquery to dynamically include controllers as needed    function controllers(controllers){        var numLoaded = 0;        for (i = 0; i < controllers.length; i++) {            $.ajaxSetup({async:false});            $.getScript('js/controllers/' + controllers[i] + '.js').success(function(){                numLoaded++;                if (numLoaded == controllers.length) {                    return true; //only return after all scripts are loaded, this is blocking, and will fail if all scripts aren't loaded.                }            });        }    }    $routeProvider        .when('/', {            templateUrl: 'views/foo.html',            resolve: {                load: function () {                    controllers(['foo'])                }            }        })        .when('/bar',{            templateUrl: 'views/bar.html',            controller: 'BarCtrl',            resolve: {                load: function () {                    controllers(['bar','foo']) //you can load multiple controller files                }            }        })        .otherwise({            redirectTo: document.location.pathname        });}]);

/views/foo.html

<section ng-controller='FooCtrl'>    {{text}}</section>

/views/bar.html

<section ng-controller='BarCtrl'>    {{text2}}</section><section ng-controller='FooCtrl'>    {{text}}</section>

/controllers/bar.js

app.registerCtrl('BarCtrl',function($scope){    $scope.text2 = 'Test';});