Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!";         } ]); 
like image 305
John Avatar asked Oct 17 '13 18:10

John


People also ask

Where do I load js files?

You can add JavaScript code in an HTML document by employing the dedicated HTML tag <script> that wraps around JavaScript code. The <script> tag can be placed in the <head> section of your HTML or in the <body> section, depending on when you want the JavaScript to load.


1 Answers

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

like image 177
lort Avatar answered Oct 04 '22 09:10

lort