Monday, April 18, 2016

Dynamically Loading AngularJS Controllers using JQuery


Hi, My code is not new and most of the code is copied from http://weblogs.asp.net/dwahlin/dynamically-loading-controllers-and-views-with-angularjs-and-requirejs

It acts as useful code snippet for myself and anyone who is looking for one.

I adapted the code to load the js files using JQuery instead of RequireJS, and it follows predefined naming convention for url, templates and js files:
  1. Url and file name: all small letters with each word separated with - (hyphen).
  2. Controller name: first letter of each word is caps with no gaps and ends with 'Ctrl'.
Save $controllerProvider as a property of angularjs app module and use RouteProvider object in $routeProvider config:
   var app = angular.module("app", ['ngRoute']);
        app.config(function ($routeProvider, $controllerProvider) {
            var route = new RouteProvider(); 
            $routeProvider
            .when('/view-one', route.resolve("view-one"))
            .when('/view2', route.resolve("view2"))
            .when('/view3', route.resolve("view3"))
            .otherwise({
                redirectTo: '/'
            });

            app.register =
            {
                controller: $controllerProvider.register
            };
        });


RouteProvider takes care of dynamically loading of js controller files using Jquery:
          var RouteProvider = function () {
            var scriptPath = "/Scripts/";
            var templatePath = "/Templates/";

            this.resolve = function (name) {
                var route = {};
                route.templateUrl = templatePath + name + ".html";
                route.controller = getControllerName(name) + "Ctrl";
                route.controllerAs = "vm";
                route.resolve = {
                    load: ['$q', '$rootScope', function ($q, $rootScope) { return loadController($q, $rootScope, scriptPath + name + ".js"); }]
                };
                return route;
            };
            var getControllerName = function (name) {
                var ctrlName = "";
                name.split("-").forEach(function (input) { ctrlName += input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase(); });
                return ctrlName;
            };
            var loadController = function ($q, $rootScope, path) {
                var defer = $q.defer();
                $.ajax({
                    dataType: "script",
                    cache: true,
                    url: path
                }).done(function () { 
                        $rootScope.$apply();
                        defer.resolve();
                });
                return defer.promise;
            };
        };


Register the controller (view3.js) after load with $controllerProvider:
    
(function (app) {
    app.register.controller('View3Ctrl', ['$http', function ($http) {
        var vm = this;
        vm.value = "Hello from view3";
        vm.gotHttp = !!$http;
    }]);
})(app || angular.module("app"));


view3.html template code:
   
<div> 
<h3>view three</h3> 
<span ng-bind="vm.value"></span> <br /> 
<div>got $http - {{vm.gotHttp}}</div> 
</div>



Libraries used: jquery, angularjs v1.4 and angular-route

2 comments:

  1. Superb. I really enjoyed very much with this article here. Really it is an amazing article I had ever read. I hope it will help a lot for all. Thank you so much for this amazing posts and please keep update like this excellent article.thank you for sharing such a great blog with us. expecting for your.
    Digital Marketing Company in India
    seo Company in India

    ReplyDelete

  2. Thanks for such awesome blog. Your article is very easy to understand, informative and provide complete overview about software testing. Please consider including rss feed in your website, so I get your recent post on my site.
    AngularJS Training in Chennai

    ReplyDelete