AngularJS add dependencies after bootstrapped
Asked Answered
S

1

7

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?

Shiny answered 1/9, 2015 at 6:0 Comment(3)
why do you think this hasn't worked? plnkr.co/edit/T7B5t9KZTKGpSAfkJxsj?p=previewAbecedary
@Abecedary If it's working, it should be showing it's running alert box.Shiny
my suspicion would be that .run doesn't happen when you add via requires.add (the app has already been run when you load the script); have you tried adding a service to app.main and calling that service from app? (I realise this may not fit your solution, but at least it would give you an idea as to whether app.main is actually loading correctly for use from app.Abecedary
M
3

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.

Multicolor answered 2/9, 2015 at 20:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.