AngularJS Mehrere ng-App innerhalb einer Seite


180

Ich habe gerade angefangen, Angular JS zu lernen und einige grundlegende Beispiele erstellt, aber ich bin mit dem folgenden Problem festgefahren.

Ich habe 2 Module und 2 Controller erstellt.

shoppingCart -> ShoppingCartController
namesList -> NamesController

Jedem Controller sind Ansichten zugeordnet. Die erste Ansicht wird gut gerendert, die zweite jedoch nicht. Es gibt keine Fehler.

http://jsfiddle.net/ep2sQ/

Bitte helfen Sie mir, dieses Problem zu lösen.

Es besteht auch die Möglichkeit, eine Konsole in View hinzuzufügen, um zu überprüfen, welche Werte vom Controller übergeben werden.

zB im folgenden div können wir console.log hinzufügen und die Controller-Werte ausgeben

<div ng-app="shoppingCart" ng-controller="ShoppingCartController">
</div>

10
Möglicherweise hilft dies: stackoverflow.com/questions/12860595/…
Cherniv

Vielen Dank, Cherniv. Dies ist sehr hilfreich und ich habe das Problem über den von Ihnen angegebenen Link gelöst. Bitte geben Sie auch an, wie Sie console.log verwenden, um den Controller in View / Template zu sichern. {{Console.log}} funktioniert nicht.
Nitin Mukesh

Bitte. Beachten Sie, dass Sie bereits "Konsole" in einer Ansicht {{item.product_name}}
ausführen

1
Ist etwas falsch daran, mehrere Apps für eine Webanwendung zu erstellen? Ich habe dieses Projekt, in dem jede HTML-Seite eine eigene App hat. Ich möchte wissen, ob die Leistung trotzdem beeinträchtigt wird.
T. Rex

Es ist zwar möglich, mehr als eine AngularJS-Anwendung pro Seite zu booten, wir testen dieses Szenario jedoch nicht aktiv. Es ist möglich, dass Sie auf Probleme stoßen, insbesondere bei komplexen Apps. Daher ist Vorsicht geboten. Siehe AngularJS Developer Guide - Bootstrap .
Georgeawg

Antworten:


190

Wie von Cherniv erwähnt, müssen wir die Module booten, um mehrere ng-Apps auf derselben Seite zu haben. Vielen Dank für alle Beiträge.

var shoppingCartModule = angular.module("shoppingCart", [])
shoppingCartModule.controller("ShoppingCartController",
  function($scope) {
    $scope.items = [{
      product_name: "Product 1",
      price: 50
    }, {
      product_name: "Product 2",
      price: 20
    }, {
      product_name: "Product 3",
      price: 180
    }];
    $scope.remove = function(index) {
      $scope.items.splice(index, 1);
    }
  }
);
var namesModule = angular.module("namesList", [])
namesModule.controller("NamesController",
  function($scope) {
    $scope.names = [{
      username: "Nitin"
    }, {
      username: "Mukesh"
    }];
  }
);
angular.bootstrap(document.getElementById("App2"), ['namesList']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>

<div id="App1" ng-app="shoppingCart" ng-controller="ShoppingCartController">
  <h1>Your order</h1>
  <div ng-repeat="item in items">
    <span>{{item.product_name}}</span>
    <span>{{item.price | currency}}</span>
    <button ng-click="remove($index);">Remove</button>
  </div>
</div>

<div id="App2" ng-app="namesList" ng-controller="NamesController">
  <h1>List of Names</h1>
  <div ng-repeat="_name in names">
    <p>{{_name.username}}</p>
  </div>
</div>


2
Sie können eine Anweisung erstellen, um dies zu tun, stattdessen stackoverflow.com/a/22898036/984780
Luis Perez

33
Die eckige Dokumentation besagt, dass beim manuellen Booten einer App NICHT die ngApp-Direktive verwendet werden darf. Ng-app = "namesList" (könnte / sollte) also entfernt werden. docs.angularjs.org/guide/bootstrap
Mike_K

4
Für diejenigen, die ng-Apps in zwei separaten js-Dateien haben, kann der folgende Code helfen. Angular.element (document) .ready (function () {angle.bootstrap (document.getElementById ("App2"), ['namesList']) ;});
Sivashanmugam Kannan

3
Hinweis: In meiner App musste ich diese Zeile "angle.bootstrap (document.getElementById (" App2 "), ['namesList'])" einfügen. in $ (Dokument) .ready Funktion
La

Es funktioniert nicht für mich. Nur die erste ng-App funktioniert richtig
SIVAKUMAR.J

120

Um mehrere Anwendungen in einem HTML-Dokument auszuführen, müssen Sie sie manuell mit angle.bootstrap () booten.

HTML

<!-- Automatic Initialization -->
<div ng-app="myFirstModule">
    ...
</div>
<!-- Need To Manually Bootstrap All Other Modules -->
<div id="module2">
    ...
</div>

JS

angular.
  bootstrap(document.getElementById("module2"), ['mySecondModule']);

Der Grund dafür ist, dass nur eine AngularJS-Anwendung pro HTML-Dokument automatisch gebootet werden kann. Das erste ng-appim Dokument gefundene Element wird verwendet, um das Stammelement für den automatischen Bootstrap als Anwendung zu definieren.

Mit anderen Worten, während es technisch möglich ist, mehrere Anwendungen pro Seite zu haben, wird nur eine ng-app-Direktive automatisch vom Angular-Framework instanziiert und initialisiert.


20
Pro HTML-Dokument kann nur eine ngAppDirektive automatisch hochgeladen werden. Sie können jedoch mehrere Apps verwenden, solange Sie die nachfolgenden manuell booten.
JaredMcAteer

@CodeHater wo befindet namesListsich dann das Modul? Könnten Sie bitte Ihre Antwort aktualisieren, damit sie klarer wird?
Eugene

Das ist falsch. Sie können mehrere ng-App haben. Siehe stackoverflow.com/a/24867989/753632
AndroidDev

3
@AndroidDev, ich folge nicht. Der Link, auf den Sie verweisen, zeigt nicht mehrere ng-app-Attribute an.
20.

42

Sie können angular.bootstrap()direkt verwenden ... das Problem ist, dass Sie die Vorteile von Richtlinien verlieren.

Zuerst müssen Sie einen Verweis auf das HTML-Element erhalten, um es booten zu können. Dies bedeutet, dass Ihr Code jetzt mit Ihrem HTML gekoppelt ist.

Zweitens ist die Assoziation zwischen den beiden nicht so offensichtlich. Mit können ngAppSie klar erkennen, welcher HTML-Code mit welchem ​​Modul verknüpft ist, und wissen, wo Sie nach diesen Informationen suchen müssen. Aber angular.bootstrap()könnte von überall in Ihrem Code aufgerufen werden.

Wenn Sie dies überhaupt tun möchten, verwenden Sie am besten eine Direktive. Welches ist, was ich getan habe. Es heißt ngModule. So würde Ihr Code aussehen, wenn Sie ihn verwenden:

<!DOCTYPE html>
<html>
    <head>
        <script src="angular.js"></script>
        <script src="angular.ng-modules.js"></script>
        <script>
          var moduleA = angular.module("MyModuleA", []);
          moduleA.controller("MyControllerA", function($scope) {
              $scope.name = "Bob A";
          });

          var moduleB = angular.module("MyModuleB", []);
          moduleB.controller("MyControllerB", function($scope) {
              $scope.name = "Steve B";
          });
        </script>
    </head>
    <body>
        <div ng-modules="MyModuleA, MyModuleB">
            <h1>Module A, B</h1>
            <div ng-controller="MyControllerA">
                {{name}}
            </div>
            <div ng-controller="MyControllerB">
                {{name}}
            </div>
        </div>

        <div ng-module="MyModuleB">
            <h1>Just Module B</h1>
            <div ng-controller="MyControllerB">
                {{name}}
            </div>
        </div>
    </body>
</html>

Den Quellcode dafür erhalten Sie unter:

http://www.simplygoodcode.com/2014/04/angularjs-getting-around-ngapp-limitations-with-ngmodule/

Es ist auf die gleiche Weise implementiert wie ngApp. Es ruft einfach angular.bootstrap()hinter die Kulissen.



7

Hier ist ein Beispiel für zwei Anwendungen auf einer HTML-Seite und zwei Conroller in einer Anwendung:

    <div ng-app = "myapp">
      <div  ng-controller = "C1" id="D1">
         <h2>controller 1 in app 1 <span id="titre">{{s1.title}}</span> !</h2>
      </div>

      <div  ng-controller = "C2" id="D2">
         <h2>controller 2 in app 1 <span id="titre">{{s2.valeur}}</span> !</h2>
      </div>
    </div>
    <script>
        var A1 = angular.module("myapp", [])

        A1.controller("C1", function($scope) {
            $scope.s1 = {};
            $scope.s1.title = "Titre 1";
         });

        A1.controller("C2", function($scope) {
            $scope.s2 = {};
            $scope.s2.valeur = "Valeur 2";
         });
    </script>

    <div ng-app="toapp" ng-controller="C1" id="App2">
        <br>controller 1 in app 2
        <br>First Name: <input type = "text" ng-model = "student.firstName">
        <br>Last Name : <input type="text" ng-model="student.lastName">
        <br>Hello : {{student.fullName()}}
        <br>
    </div>

    <script>
        var A2 = angular.module("toapp", []);
        A2.controller("C1", function($scope) {
            $scope.student={
                firstName:"M",
                lastName:"E",
                fullName:function(){
                    var so=$scope.student;
                    return so.firstName+" "+so.lastName;
                }
            };
        });
        angular.bootstrap(document.getElementById("App2"), ['toapp']);
    </script>
<style>
    #titre{color:red;}
    #D1{ background-color:gray; width:50%; height:20%;}
    #D2{ background-color:yellow; width:50%; height:20%;}
    input{ font-weight: bold; }
</style>


6

Sie können mehrere Module in einem rootModule zusammenführen und dieses Modul als ng-app einem übergeordneten Element zuweisen, z. B. body-Tag.

Code ex:

    <!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="namesController.js"></script>
<script src="myController.js"></script>
<script>var rootApp = angular.module('rootApp', ['myApp1','myApp2'])</script>
<body ng-app="rootApp">

<div ng-app="myApp1" ng-controller="myCtrl" >
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>

<div ng-app="myApp2" ng-controller="namesCtrl">
<ul>
  <li ng-bind="first">{{first}}
  </li>
</ul>
</div>

</body>
</html>

4
Sie verschachteln zwei verschiedene Apps in der rootApp. Angular erlaubt keine Verschachtelung von Apps
Codin

4

         var shoppingCartModule = angular.module("shoppingCart", [])
          shoppingCartModule.controller("ShoppingCartController",
           function($scope) {
             $scope.items = [{
               product_name: "Product 1",
               price: 50
             }, {
               product_name: "Product 2",
               price: 20
             }, {
               product_name: "Product 3",
               price: 180
             }];
             $scope.remove = function(index) {
               $scope.items.splice(index, 1);
             }
           }
         );
         var namesModule = angular.module("namesList", [])
          namesModule.controller("NamesController",
           function($scope) {
             $scope.names = [{
               username: "Nitin"
             }, {
               username: "Mukesh"
             }];
           }
         );


         var namesModule = angular.module("namesList2", [])
          namesModule.controller("NamesController",
           function($scope) {
             $scope.names = [{
               username: "Nitin"
             }, {
               username: "Mukesh"
             }];
           }
         );


         angular.element(document).ready(function() {
           angular.bootstrap(document.getElementById("App2"), ['namesList']);
           angular.bootstrap(document.getElementById("App3"), ['namesList2']);
         });
<!DOCTYPE html>
<html>

<head>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>

</head>

<body>

  <div id="App1" ng-app="shoppingCart" ng-controller="ShoppingCartController">
    <h1>Your order</h1>
    <div ng-repeat="item in items">
      <span>{{item.product_name}}</span>
      <span>{{item.price | currency}}</span>
      <button ng-click="remove($index);">Remove</button>
    </div>
  </div>

  <div id="App2" ng-app="namesList" ng-controller="NamesController">
    <h1>List of Names</h1>
    <div ng-repeat="_name in names">
      <p>{{_name.username}}</p>
    </div>
  </div>
  <div id="App3" ng-app="namesList2" ng-controller="NamesController">
    <h1>List of Names</h1>
    <div ng-repeat="_name in names">
      <p>{{_name.username}}</p>
    </div>
  </div>


</body>

</html>


Nur eine Erweiterung, um mehrere ng-Apps auf einer Seite zu haben. Ich musste einfach sowohl saeb-amini als auch @Nithin Mukesh Code kombinieren - Danke euch beiden
Praneeth

Dieses Konzept funktioniert für mich. angle.element (document) .ready (function () {angle.bootstrap (document.getElementById ("App2"), ['namesList']); angle.bootstrap (document.getElementById ("App3"), ['namesList2' ]);});
SIVAKUMAR.J

2

Es wird nur eine App automatisch initialisiert. Andere müssen wie folgt manuell initialisiert werden:

Syntax:

angular.bootstrap(element, [modules]);

Beispiel:

<!DOCTYPE html>
<html>

<head>
  <script src="https://code.angularjs.org/1.5.8/angular.js" data-semver="1.5.8" data-require="angular.js@1.5.8"></script>
  <script data-require="ui-router@0.2.18" data-semver="0.2.18" src="//cdn.rawgit.com/angular-ui/ui-router/0.2.18/release/angular-ui-router.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script>
    var parentApp = angular.module('parentApp', [])
  .controller('MainParentCtrl', function($scope) {
    $scope.name = 'universe';
  });



var childApp = angular.module('childApp', ['parentApp'])
  .controller('MainChildCtrl', function($scope) {
    $scope.name = 'world';
  });


angular.element(document).ready(function() {
  angular.bootstrap(document.getElementById('childApp'), ['childApp']);
});
    
  </script>
</head>

<body>
  <div id="childApp">
    <div ng-controller="MainParentCtrl">
      Hello {{name}} !
      <div>
        <div ng-controller="MainChildCtrl">
          Hello {{name}} !
        </div>
      </div>
    </div>
  </div>
</body>

</html>

AngularJS API


1

Sie können eine Root-ng-App definieren und in dieser ng-App können Sie mehrere nd-Controler definieren. So was

    <!DOCTYPE html>
    <html>
    <script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>

<style>
         table, th , td {
            border: 1px solid grey;
            border-collapse: collapse;
            padding: 5px;
         }

         table tr:nth-child(odd) {
            background-color: #f2f2f2;
         }

         table tr:nth-child(even) {
            background-color: #ffffff;
         }
      </style>

     <script>
      var mainApp = angular.module("mainApp", []);

      mainApp.controller('studentController1', function ($scope) {
      $scope.student = {
      firstName: "MUKESH",
      lastName: "Paswan",

      fullName: function () {
         var studentObject;
         studentObject = $scope.student;
         return studentObject.firstName + " " + studentObject.lastName;
                     }
                 };
             });

             mainApp.controller('studentController2', function ($scope) {
                 $scope.student = {
                     firstName: "Mahesh",
                     lastName: "Parashar",
                     fees: 500,

                     subjects: [
                        { name: 'Physics', marks: 70 },
                        { name: 'Chemistry', marks: 80 },
                        { name: 'Math', marks: 65 },
                        { name: 'English', marks: 75 },
                        { name: 'Hindi', marks: 67 }
                     ],

                     fullName: function () {
                         var studentObject;
                         studentObject = $scope.student;
                         return studentObject.firstName + " " + studentObject.lastName;
                     }
                 };
             });
          </script>

    <body>
    <div ng-app = "mainApp">
    <div id="dv1"  ng-controller = "studentController1">
    Enter first name: <input type = "text" ng-model = "student.firstName"><br/><br/> Enter last name: <input type = "text" ng-model = "student.lastName"><br/>
    <br/>
     You are entering: {{student.fullName()}}
    </div>

    <div id="dv2" ng-controller = "studentController2">
     <table border = "0">
                <tr>
                   <td>Enter first name:</td>
                   <td><input type = "text" ng-model = "student.firstName"></td>
                </tr>

                <tr>
                   <td>Enter last name: </td>
                   <td>
                      <input type = "text" ng-model = "student.lastName">
                   </td>
                </tr>

                <tr>
                   <td>Name: </td>
                   <td>{{student.fullName()}}</td>
                </tr>

                <tr>
                   <td>Subject:</td>

                   <td>
                      <table>
                         <tr>
                            <th>Name</th>.
                            <th>Marks</th>
                         </tr>

                         <tr ng-repeat = "subject in student.subjects">
                            <td>{{ subject.name }}</td>
                            <td>{{ subject.marks }}</td>
                         </tr>

                      </table>
                   </td>

                </tr>
             </table>

          </div>
    </div>

    </body>
    </html>

1

// root-app
const rootApp = angular.module('root-app', ['app1', 'app2E']);

// app1
const app11aa = angular.module('app1', []);
app11aa.controller('main', function($scope) {
  $scope.msg = 'App 1';
});

// app2
const app2 = angular.module('app2E', []);
app2.controller('mainB', function($scope) {
  $scope.msg = 'App 2';
});

// bootstrap
angular.bootstrap(document.querySelector('#app1a'), ['app1']);
angular.bootstrap(document.querySelector('#app2b'), ['app2E']);
<!-- angularjs@1.7.0 -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.0/angular.min.js"></script>

<!-- root-app -->
<div ng-app="root-app">

  <!-- app1 -->
  <div id="app1a">
    <div ng-controller="main">
      {{msg}}
    </div>
  </div>

  <!-- app2 -->
  <div id="app2b">
    <div ng-controller="mainB">
      {{msg}}
    </div>
  </div>

</div>


0

Ich habe deine jsfiddle modifiziert, kann das meiste Modul als rootModule für den Rest der Module machen. Unten Änderungen an Ihrer jsfiddle aktualisiert.

  1. Das zweite Modul kann in RootModule injiziert werden.
  2. In HTML zweite definierte ng-App innerhalb der Root ng-App platziert.

Updated JsFiddle: http://jsfiddle.net/ep2sQ/1011/


Irgendeine Idee, warum dies nur die erste auswertet ng-app? jsfiddle.net/vwcbtzdg
Si8

Zuerst nur automatisch initialisiert, andere müssen manuell initialisiert werden
Mano

0

Verwenden Sie angular.bootstrap(element, [modules], [config])diese Option, um die AngularJS-Anwendung manuell zu starten (weitere Informationen finden Sie im Bootstrap-Handbuch ).

Siehe folgendes Beispiel:

// root-app
const rootApp = angular.module('root-app', ['app1', 'app2']);

// app1
const app1 = angular.module('app1', []);
app1.controller('main', function($scope) {
  $scope.msg = 'App 1';
});

// app2
const app2 = angular.module('app2', []);
app2.controller('main', function($scope) {
  $scope.msg = 'App 2';
});

// bootstrap
angular.bootstrap(document.querySelector('#app1'), ['app1']);
angular.bootstrap(document.querySelector('#app2'), ['app2']);
<!-- angularjs@1.7.0 -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.0/angular.min.js"></script>

<!-- root-app -->
<div ng-app="root-app">

  <!-- app1 -->
  <div id="app1">
    <div ng-controller="main">
      {{msg}}
    </div>
  </div>

  <!-- app2 -->
  <div id="app2">
    <div ng-controller="main">
      {{msg}}
    </div>
  </div>

</div>


-5
<html>
<head>
    <script src="angular.min.js"></script>
</head>
<body>
<div ng-app="shoppingCartParentModule" >
     <div ng-controller="ShoppingCartController">
        <h1>Your order</h1>
        <div ng-repeat="item in items">
            <span>{{item.product_name}}</span>
            <span>{{item.price | currency}}</span>
            <button ng-click="remove($index);">Remove</button>
        </div>
    </div>

    <div ng-controller="NamesController">
        <h1>List of Names</h1>
        <div ng-repeat="name in names">
            <p>{{name.username}}</p>
        </div>
    </div>
</div>
</body>
<script>
var shoppingCartModule = angular.module("shoppingCart", [])
            shoppingCartModule.controller("ShoppingCartController",
                function($scope) {
                    $scope.items = [
                        {product_name: "Product 1", price: 50},
                        {product_name: "Product 2", price: 20},
                        {product_name: "Product 3", price: 180}
                    ];
                    $scope.remove = function(index) {
                        $scope.items.splice(index, 1);
                    }
                }
            );
            var namesModule = angular.module("namesList", [])
            namesModule.controller("NamesController",
                function($scope) {
                    $scope.names = [
                        {username: "Nitin"},
                        {username: "Mukesh"}
                    ];
                }
            );
   angular.module("shoppingCartParentModule",["shoppingCart","namesList"])
</script>
</html>

1
Fügen Sie Ihrer Antwort eine Beschreibung hinzu, was Sie gepostet haben
Abhinav Singh Maurya

1
Benötigt Kommentare, die erklären, was los ist! Netter Versuch!
Eric Brown - Cal
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.