0

I have an app in Angular which will become large over time and I do not want users to load all the controllers upfront inside the index.html. To overcome some scaling issues I would like to load the controller for a given view when the user visits that given view. I do not want to statically define the controller and view in my router.js but rather source them dynamically. My router.js looks as follows:

var app = angular.module('MyApp', ['ngRoute', 'ui.bootstrap']);
app.config(function ($routeProvider) {
    $routeProvider
        .when('/', {
            controller: 'HomeController',
            templateUrl: 'views/home.html'
        })
        .when('/portfolio/:page', {
            controller: 'TopLevelController',
            templateUrl: function(params){ return 'views/portfolio/'+params.page+'.html';}
        })
        .otherwise({
            redirectTo: '/'
        });
});

There will be a large number of view inside the portfolio folder and each view will have its own controller. Each view is very different due to visualisations and the usage of directives.

One solution I thought would help was found on this link, where I have a top level controller and then source the required JS through this controller.

My top level controller looks like:

app.controller('TopLevelController', ['$scope', '$route', '$controller', function($scope, $route, $controller) {    
    $scope.loadScript = function(url, type, charset) {
        if (type===undefined) type = 'text/javascript';
        if (url) {
            var script = document.querySelector("script[src*='"+url+"']");
            if (!script) {
                var heads = document.getElementsByTagName("head");
                if (heads && heads.length) {
                    var head = heads[0];
                    if (head) {
                        script = document.createElement('script');
                        script.setAttribute('src', url);
                        script.setAttribute('type', type);
                        if (charset) script.setAttribute('charset', charset);
                        head.appendChild(script);
                    }
                }
            }
            return script;
        }
    };

    var controllerToLoad = $route.current.params.page+'Controller.js';

    $scope.loadScript('js/controllers/portfolio/'+controllerToLoad, 'text/javascript', 'utf-8');

}]);

An example view in side portfolio is 'PDB.html' and looks like as follows:

<html>
<body ng-controller="PDBController">
{{test}}
Static Text
</body>
</html>

The PDBController looks like:

app.controller('PDBController', ['$scope', '$http', function($scope, $http) {
    $scope.test = "inside PDBController";
    console.log("i exist");
}]);

But when I visit then view all I get is: enter image description here

I do not see the text "inside PDBController" nor do I see "i exists" in the console output. Could anyone point out where I cam going wrong or provide a solution?

Community
  • 1
  • 1
Harpal
  • 12,057
  • 18
  • 61
  • 74
  • There is no lazy load of component scripts built into angular. Need third party modules to do it – charlietfl Mar 06 '16 at 21:10
  • The controllers are not instantiated unless you add a partial with them in it. So they are not 'loaded', but you need to define them. You need a lot of controllers with tons of code to get into scaling issues. – kuhnroyal Mar 06 '16 at 22:05

0 Answers0