Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS add dependencies after bootstrapped

I want to add dependencies after AngularJS is bootstrapped. I tried to do it via app.requires.push('app.main'); as suggested in this post (re-open and add dependencies to an already bootstrapped application). However, it does not work.

Here's my example code:

index.html

<!DOCTYPE html>
<html ng-app="app">

  <head>
    <link rel="stylesheet" href="style.css">
    <script type="text/javascript" src="https://code.angularjs.org/1.4.3/angular.min.js"></script>
    <script src="script.js"></script>

  </head>
  <body>
    <h1>Hello Plunker!</h1>
  </body>

</html>

script.js

   var app = angular
    .module('app',[])
    .run(function($http){
            $http.get("script2.js").success(function(data){
                eval(data);
                //app.requires.push('app.main');
            }).error(function(){
              alert("error");
          });
    });

script2.js

alert("it's loaded");
angular.module('app.main', [])
.run(function(){
  alert("it's running");
});
console.log(app);
app.requires.push('app.main');

http://plnkr.co/edit/gN2kkoyqamB4OANXMUjA

Why is it doesn't work? How can I fix it?

like image 409
user1995781 Avatar asked Sep 01 '15 06:09

user1995781


1 Answers

moduleName.requires is undocumented, poorly understood and used only by Angular injector. Injector, in turn, is called during bootstrapping (via either ng-app or angular.bootstrap) or creating new injector with angular.injector.

Once the app is bootstrapped and config/run phases are over, new config/run blocks can't be invoked. The same concerns moduleName.directive, moduleName.controller and other module methods, all of them are supposed to be called before the app is bootstrapped. Hence, they are unsuitable for defining module asynchronously.

Newly defined run block can be called by creating an injector explicitly (and it means that a new app instance is created):

var newApp = angular.injector(['app.main']);

It's primary use is testing and it has limited application in production - the newly instantiated app and its services can't communicate with bootstrapped app because service singletons are different.

There are a few solutions for lazy loading in Angular, the most comprehensive is ocLazyLoad.

like image 196
Estus Flask Avatar answered Sep 17 '22 05:09

Estus Flask