Angular JS: How to load js files in partials

Very new to AngularJS, I am guessing the term for what I am trying to do is lazy load. I have looked at several different blogs and I have not found a complete working solution that is purely using AngularJS.

I understand that if I put the <script src="js/process1.js"></script> in index.html, all works fine, I am trying to cut down on the amount of js that is pulled down on the initial load.

With the script tag sitting in the partial, it is never loaded so the P1Ctrl is never created. So currently, if a user go into the application and never goes to process55, the user still has the code there for process55 even though it was never used.

Is there a way to load the file and inject the objects created in the process1.js into the app defined in main, at the time process1 route is executed?

index.html:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Large Angular App</title>
    <link rel="stylesheet" href="lib/foundation/css/foundation.min.css" />
</head>
<body ng-app="largeApp" ng-controller="LargeAppController">

    <div>
        <a href="#/home">Home</a> | <a href="#/process1">Process1</a>
    </div>
    <br/>
    <br/>
    <br/>

    <ng-view>Test</ng-view>


    <script type="text/javascript" src="lib/jquery/jquery.min.js"></script>
    <script type="text/javascript" src="lib/angular/angular.js"></script>
    <script type="text/javascript" src="lib/angular/angular-route.js"></script>
    <script type="text/javascript" src="js/main.js"></script>
</body>
</html>

js/main.js:

var app = angular.module("largeApp", ['ngRoute']);

var appCtrl = app.controller("LargeAppController", function(){});


app.config(function ($routeProvider, $controllerProvider) {
    // save references to the providers

    app.registerCtrl = $controllerProvider.register,

    $routeProvider.when('/', {templateUrl: 'partials/home.html'});
      //Thinking I need to set up a resolve to fire off a script loader to load js.
    $routeProvider.when('/process1', {templateUrl: 'partials/process1/process1.html'});
    $routeProvider.otherwise({redirectTo: '/'});
});

partials/home.html:

   <div>
    Home Page
   </div>

partials/process1.html:

<script type="text/javascript" src="js/process1/Process1Controller.js"></script>
Process 1 {{process1data}}

js/process1.js:

console.log("I made it here");

app.registerCtrl('Process1Controller',function($scope){
            $scope.process1data = "Hello!";
        }
]);

Answers:

Answer

To implement lazy loading of controllers in simple way, you have to do the following:

Save $controllerProvider.register (which is the only method to add a controller into already bootstrapped AngularJS app) to variable in your app (main.js):

var app = angular.module('app',["ngRoute"]);
app.config(['$routeProvider', '$controllerProvider',
    function($routeProvider, $controllerProvider) {
        // remember mentioned function for later use
        app.registerCtrl = $controllerProvider.register;
        //your routes
        $routeProvider.when('/', {templateUrl: 'partials/home.html'});
        $routeProvider.when('/process1', {templateUrl: 'partials/process1.html'});
        $routeProvider.otherwise({redirectTo: '/'});
    }
]);

process1.html:

<script src="js/process1.js"></script>
<div ng-controller="P1Ctrl">
    {{content}}
</div>

And now, in process1.js you use our registerCtrl:

app.registerCtrl('P1Ctrl', function($scope)
{
   $scope.content = '...'; 
});

index.html probably remains the same. Check if your process1.js is being loaded (simply using console.log() right in the body of process1.js, not in P1Ctrl controller). If it isn't, include jQuery before Angular:

<script src="lib/jquery/jquery.js"></script>
<script src="lib/angular/angular.js"></script>

IMPORTANT: This method doesn't work with angular 1.2.0-rc.2 and 1.2.0-rc.3, because this little trick with jQuery doesn't work.

For more complex (and prettier) solution, with .js files as dependencies in route definitions, check that article: http://ify.io/lazy-loading-in-angularjs/ - it also works with rc.2 and rc.3. Here is plunk implementing described method: http://plnkr.co/edit/ukWikO5TVDtQ1l9WlrGD

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.