2

I tried giving two ng-app in an application , when i gave two ng-app like

 <body>
    <div ng-app="A">
        <div ng-controller="AC">
        </div>
    </div>


    <div ng-app="B">
        <div ng-controller="BC">
        </div>
    </div>

</body>

Then second ng-app does not work.

But when i change the scope of first ng-app="A" from div to body then both works fine like

<body ng-app="A">
<div>
    <div ng-controller="AC">
    </div>
</div>


<div ng-app="B">
    <div ng-controller="BC">
    </div>
</div>
</body>

Can anyone let me know why this behavior as i am quite new to angular. I wanted to know why it worked as i didn't called angular.bootstrap on the second one.I tried searching but i didn't got how it is working when changing the scope of ng-app from div to body.

Find the fiddle for the same https://jsfiddle.net/maddyjolly2112/wyfd0djp/1/ and mind copying the js into the same .

E_net4
  • 27,810
  • 13
  • 101
  • 139
Mandeep Singh
  • 1,287
  • 14
  • 34
  • Yeah George ,but it is working, i am trying to create a plunkr for the same – Mandeep Singh Jan 11 '16 at 16:06
  • Make sure your plunkr takes into account multiple things broadcasting from the rootscope that are named the same. – George Stocker Jan 11 '16 at 16:07
  • Some issues I see with the question are: Unclear what you're asking ("Why this behavior is" -- why *what* behavior is?). The documentation is quite clear (as I lay out in my answer) on what you should and should not do; without understanding your specific question; it's hard to know what you want from us. – George Stocker Jan 12 '16 at 15:38
  • I wanted to know how the angular framework read it and why it worked when i nested the second ng-app inside the first. Does it override it or what?? – Mandeep Singh Jan 12 '16 at 15:48
  • 1
    You'll have to clarify 'worked'. If you pass a trivial example that doesn't exercise the specific parts of the framework that are bound to elements and scope (directives; but some template parsing), then just about anything will 'work'. Also, if you want to know why your trivial example 'worked', the source code is available for you to read. https://github.com/angular/angular.js/blob/93c7251f5f40bdbe050c74130d90331613d968a2/src/Angular.js#L1529 – George Stocker Jan 12 '16 at 15:55

3 Answers3

6

Docs say: Don't use ngApp when instantiating multiple angular applications.

The reason you can't do this is laid out in the docs for the ngApp directive.

Only one AngularJS application can be auto-bootstrapped per HTML document. The first ngApp found in the document will be used to define the root element to auto-bootstrap as an application. To run multiple applications in an HTML document you must manually bootstrap them using angular.bootstrap instead. AngularJS applications cannot be nested within each other.

But Bootstraping multiple Angular apps is possible...

To bootstrap multiple Angular apps, you have to reference each, and they logically can't be nested, or sharing an element; they need to be separate from each other. Because of this, you cannot use the directive, ngApp:

  <html>
    <head></head>
    <body>
    <script src="angular.js"></script>
    <div id="appElementA"></div>
    <div id="appElementB"></div>
    <script>
      var app = angular.module('A', [])
      .controller('AB', function($scope) {
          $scope.greeting = 'Welcome!';
      });
      var appElementA = document.getElementById('divAppA');
      angular.bootstrap(appElementA, ['A']);
    var bApp = angular.module('B', [])
      .controller('BB', function($scope) {
          $scope.greeting = 'Welcome to B app!';
      });
      var appElementB = document.getElementById('divAppB');
      angular.bootstrap(appElementB, ['B']);
    </script>
    </body>
    </html>

The above code would be how you'd do it for your apps. You'd then have to be sure you're assigning the controllers to the right angular application (app vs bApp, in the above example.)

But don't nest them!

You claim it 'works' when you nest them, but you should be aware that it doesn't work, it just doesn't crash hard. Don't have multiple angular applications nested. You'll encounter weird issues, especially if you have multiple variables named the same bound to the $rootScope.

But you can nest them without ill effects, right?

If you're intent on having two Angular apps nested; it's possible but extremely version specific and liable to break in weird ways. This Stack Overflow answer talks about it.

Community
  • 1
  • 1
George Stocker
  • 57,289
  • 29
  • 176
  • 237
  • It's ok guys, i do studied the same that for this we have to manually bootstrap them using angular.bootstrap but in my case i changed the scope of ng-app=A from div to body which lead to working of ng-app="B". I wanted to know why it worked as i didn't called angular.bootstrap on the second one? – Mandeep Singh Jan 11 '16 at 15:57
  • @MandeepSingh It doesn't "work", it just doesn't crash hard. You're going to have weird behavior by doing that. I linked to another Stack Overflow question where they talk about this. – George Stocker Jan 11 '16 at 16:02
  • you are absolutely right regarding the same, can you help in knowing how it has been compiled by angular ,for the first when both are in different div and for the second case when i moved the first ng-app to he body section – Mandeep Singh Jan 11 '16 at 16:41
  • @MandeepSingh If you don't want an issue, you need to have those elements at the same level, not nested. You also have to use elements that are scoped appropriately; if you use `body` in one and `div` in the other, you're going to have problems. – George Stocker Jan 11 '16 at 16:44
  • you are right, we should keep rest of the things modularised, i just want to know how this worked, no doubt your answer had provided so many things to me except how it worked? , just help me for the same, i will accept your answer as well – Mandeep Singh Jan 11 '16 at 16:52
0

From Angular's official docs :

Only one AngularJS application can be auto-bootstrapped per HTML document. The first ngApp found in the document will be used to define the root element to auto-bootstrap as an application. To run multiple applications in an HTML document you must manually bootstrap them using angular.bootstrap instead. AngularJS applications cannot be nested within each other.

Source : https://docs.angularjs.org/api/ng/directive/ngApp

If the question is : why the second example works and not the first, the answer is in the link above > Angular needs the first ngApp to be placed near the root element of the page (html or body).

enguerranws
  • 8,087
  • 8
  • 49
  • 97
0

As George mentioned, manual bootstrapping will work. In html, use id instead of ng-app.

In script

var dvFirst = document.getElementById('dvFirst');
var dvSecond = document.getElementById('dvSecond');

angular.element(document).ready(function() {
   angular.bootstrap(dvFirst, ['firstApp']);
   angular.bootstrap(dvSecond, ['secondApp']);
});

Here is a working plunker http://plnkr.co/edit/1SdZ4QpPfuHtdBjTKJIu?p=preview

Hari Das
  • 10,145
  • 7
  • 62
  • 59