【问题标题】:AngularJS Multiple ng-app within a pageAngularJS 页面内的多个 ng-app
【发布时间】:2013-09-05 10:47:23
【问题描述】:

我刚刚开始学习 Angular JS 并创建了一些基本示例,但是我遇到了以下问题。

我已经创建了 2 个模块和 2 个控制器。

shoppingCart -> ShoppingCartController
namesList -> NamesController

每个控制器都有关联的视图。第一个视图渲染得很好,但第二个没有渲染。没有错误。

http://jsfiddle.net/ep2sQ/

请帮我解决这个问题。

还有可能在 View 中添加控制台以检查从 Controller 传递的值。

例如在下面的div中我们可以添加console.log并输出控制器值

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

【问题讨论】:

  • 这可能会有所帮助:stackoverflow.com/questions/12860595/…
  • 谢谢切尔尼夫。这非常有帮助,我使用您提供的链接解决了问题。请您还提供有关如何使用 console.log 在视图/模板中转储控制器的信息 {{console.log}} 不起作用。
  • 欢迎您。请注意,您已经在视图中执行“控制台”,这:{{item.product_name}} 实际上“打印”了模型中的值
  • 为一个webapp创建多个app有什么问题吗?我有这个项目,每个 html 页面都有自己的应用程序,我想知道性能是否会受到影响?
  • 虽然每页可以引导多个 AngularJS 应用程序,但我们不会主动针对这种情况进行测试。您可能会遇到问题,尤其是对于复杂的应用程序,因此建议您谨慎行事。见AngularJS Developer Guide - Bootstrap

标签: angularjs


【解决方案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>

【讨论】:

    【解决方案2】:

    只有一个应用程序会自动初始化。其他的要手动初始化如下:

    语法:

    angular.bootstrap(element, [modules]);
    

    例子:

    <!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

    【讨论】:

      【解决方案3】:

      使用angular.bootstrap(element, [modules], [config]) 手动启动AngularJS 应用程序(有关详细信息,请参阅Bootstrap guide)。

      看下面的例子:

      // 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>

      【讨论】:

        【解决方案4】:

        我已经修改了您的 jsfiddle,可以将最顶层的模块作为其余模块的 rootModule。 下面的修改在您的 jsfiddle 上更新。

        1. 可以在 RootModule 中注入第二个模块。
        2. 在 Html 中第二个定义的 ng-app 放置在 Root ng-app 内。

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

        【讨论】:

        • 知道为什么这只评估第一个ng-app吗? jsfiddle.net/vwcbtzdg
        • 第一次只能自动初始化,其他要手动初始化
        【解决方案5】:

        这是一个 html 页面中的两个应用程序和一个应用程序中的两个控制器的示例:

            <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】:

                   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>

          【讨论】:

          • 只是在一个页面中拥有多个 ng-app 的扩展,我只需要结合 saeb-amini 和 @Nithin Mukesh 代码 -- 谢谢你们俩
          • 这个概念对我有用。 angular.element(document).ready(function() { angular.bootstrap(document.getElementById("App2"), ['namesList']); angular.bootstrap(document.getElementById("App3"), ['namesList2' ]); });
          【解决方案7】:

          在我的情况下,我必须将我的第二个应用程序的引导程序包装在 angular.element(document).ready 中才能正常工作:

          angular.element(document).ready(function() {
            angular.bootstrap(document.getElementById("app2"), ["app2"]);
          });   
          

          【讨论】:

          【解决方案8】:

          所以基本上正如 Cherniv 所提到的,我们需要引导模块以在同一页面中拥有多个 ng-app。非常感谢所有的投入。

          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>

          【讨论】:

          • 你可以创建一个指令来代替stackoverflow.com/a/22898036/984780
          • 角度文档说,当手动引导应用程序时,不要使用 ngApp 指令。所以 ng-app="namesList" (可以/应该)被reoved。 docs.angularjs.org/guide/bootstrap
          • 对于那些在两个单独的 js 文件中拥有 ng-app 的人,下面的代码可能会有所帮助 angular.element(document).ready(function() { angular.bootstrap(document.getElementById("App2" ), ['namesList']); });
          • 注意:在我的应用程序中,我必须把这一行"angular.bootstrap(document.getElementById("App2"), ['namesList']);"在 $(document).ready 函数中
          • 它对我不起作用。只有第一个 ng-app 可以正常工作
          【解决方案9】:
          <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>
          

          【讨论】:

          • 在您发布的内容中添加描述
          • 需要 cmets 解释发生了什么!不错的尝试!
          【解决方案10】:

          您可以定义一个 Root ng-App,在这个 ng-App 中您可以定义多个 nd-Controler。像这样

              <!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>
          

          【讨论】:

            【解决方案11】:

            您可以将多个模块合并到一个 rootModule 中,并将该模块分配为 ng-app 到上级元素例如:body 标签。

            代码示例:

                <!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>
            

            【讨论】:

            • 您在 rootApp 中嵌套了两个不同的应用程序,Angular 不允许嵌套应用程序
            【解决方案12】:

            要在 HTML 文档中运行多个应用程序,您必须使用 angular.bootstrap() 手动引导它们

            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']);
            

            这样做的原因是每个 HTML 文档只能自动引导一个 AngularJS 应用程序。在文档中找到的第一个 ng-app 将用于定义根元素以作为应用程序自动引导。

            换句话说,虽然从技术上讲,每个页面可以有多个应用程序,但只有一个 ng-app 指令会被 Angular 框架自动实例化和初始化。

            【讨论】:

            • 每个 HTML 文档只能 auto-bootloaded 一个 ngApp 指令,但您可以拥有多个应用程序,只要您手动引导后续应用程序。
            • @CodeHater 那么namesList 模块在哪里?您能否更新您的答案,以便更清楚?
            • 这是错误的。你可以有多个 ng-app。见stackoverflow.com/a/24867989/753632
            • @AndroidDev,我不关注。您引用的链接未显示多个 ng-app 属性。
            【解决方案13】:

            你可以直接使用angular.bootstrap()...问题是你失去了指令的好处。

            首先,您需要获取对 HTML 元素的引用以引导它,这意味着您的代码现在已与 HTML 耦合。

            其次,两者之间的关联并不那么明显。使用ngApp,您可以清楚地看到什么 HTML 与什么模块相关联,并且您知道在哪里查找该信息。但是angular.bootstrap() 可以从代码中的任何位置调用。

            如果您打算这样做,最好的方法是使用指令。这就是我所做的。它被称为ngModule。这是您的代码使用它的样子:

            <!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>
            

            您可以在以下位置获取它的源代码:

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

            它的实现方式与ngApp 相同。它只是在幕后调用angular.bootstrap()

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-10-01
              • 1970-01-01
              • 2014-01-21
              相关资源
              最近更新 更多