AngularJS Кілька ng-додатків на сторінці


180

Я щойно почав вивчати 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>

10
можливо, це допоможе: stackoverflow.com/questions/12860595/…
Чернів

Дякую Чернів. Це дуже корисно, і я вирішив проблему за допомогою наданого вами посилання. Будь ласка, ви також можете надати інформацію про те, як використовувати console.log для скидання контролера в режимі View / Template {{console.log}} не працює.
Нітін Мукеш

будь ласка. зауважте, що ви вже робите "консоль" у видах, це: {{item.product_name}}насправді "друкує" значення з вашої моделі
Чернів

1
Чи щось не так у створенні кількох додатків для веб-сайту? У мене є цей проект, де на кожній html-сторінці є власне додаток, я хочу знати, чи вплине на продуктивність в будь-якому випадку?
Т. Рекс

Хоча можна завантажувати більше однієї програми AngularJS на сторінку, ми не проводимо тестування на цей сценарій. Цілком можливо, що ви зіткнетеся з проблемами, особливо зі складними додатками, тому рекомендується обережність. Див. Посібник для розробників AngularJS - завантажувальний пристрій .
georgeawg

Відповіді:


190

Отже, як згадує Чернів, нам потрібно завантажувати модулі, щоб мати кілька ng-додатків на одній сторінці. Велике спасибі за всі матеріали.

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
Ви можете створити директиву для цього замість stackoverflow.com/a/22898036/984780
Луїс Перес

33
У кутовій документації зазначено, що під час завантаження програми вручну НЕ слід використовувати директиву ngApp. Отже, ng-app = "namesList" (міг / повинен) бути відновлений. docs.angularjs.org/guide/bootstrap
Mike_K

4
Для тих, хто має ng-додаток у двох окремих js-файлах, наведений нижче код може допомогти angular.element (document) .ready (function () {angular.bootstrap (document.getElementById ("App2"), ['namesList']) ;});
Сіва Каннан

3
Примітка: у своєму додатку я повинен був поставити цей рядок "angular.bootstrap (document.getElementById (" App2 "), ['namesList']);" в $ (документ). вже функція
La

Це не працює для мене. Лише перший ng-додаток працює правильно
SIVAKUMAR.J

120

Для запуску декількох додатків у документі 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']);

Причиною цього є те, що лише один додаток AngularJS може бути автоматично завантажений на один документ HTML. Перший ng-appзнайдений у документі буде використаний для визначення кореневого елемента для автоматичного завантаження як програми.

Іншими словами, хоча технічно можливо мати кілька додатків на сторінку, лише одна директива щодо додатків буде автоматично автоматизована та ініціалізована рамкою Angular.


20
За один документ HTML ngAppможна завантажувати лише одну директиву, але ви можете мати кілька додатків, поки ви вручну завантажуєте наступні.
JaredMcAteer

@CodeHater, де тоді знаходиться namesListмодуль? Чи можете ви, будь ласка, оновити свою відповідь, щоб було зрозуміліше?
Євген

Це неправильно. У вас МОЖЕ бути кілька ng-додатків. Див stackoverflow.com/a/24867989/753632
AndroidDev

3
@AndroidDev, я не стежу за цим. Посилання, на яке ви посилаєтесь, не містить декількох атрибутів ng-додатків.
Jpnh

42

Ви можете використовувати 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()за лаштунками.


9

У моєму випадку мені довелося завершити завантаження другого додатка, angular.element(document).readyщоб воно працювало:

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

V1.6 Вимкнено: використовувати angular.element(callback)замість angular.element(document).ready(callback)). Див. Посилання на API AngularJS angular.element API . Також github.com/angular/angular.js/commit/…
georgeawg

7

Ось приклад двох додатків на одній 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

Ви можете об'єднати декілька модулів в одному rootModule та призначити цей модуль як ng-додаток до вищого елемента ex: body tag.

код, наприклад:

    <!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
Ви вкладаєте дві різні програми всередині rootApp, Angular не дозволяє вкладати програми
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>


Просто розширення, щоб мати кілька ng-додатків на одній сторінці, я повинен був просто поєднати і saeb-amini, і @Nithin Mukesh код - Дякую вам обом
Praneeth

Ця концепція працює для мене. angular.element (document) .ready (function () {angular.bootstrap (document.getElementById ("App2"), ['namesList']); angular.bootstrap (document.getElementById ("App3"), ['namesList2' ]);});
SIVAKUMAR.J

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


1

Ви можете визначити кореневу ng-програму, і в цій ng-додатку можна визначити кілька nd-контролерів. Подобається це

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

Я змінив вашу jsfiddle, може зробити найкращий модуль як rootModule для решти модулів. Нижче Модифікації оновлені у вашій jsfiddle.

  1. Другий модуль можна вводити в RootModule.
  2. У другому Html визначеному ng-додатку, розміщеному всередині кореневого ng-додатка.

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


Будь-яка ідея, чому це лише перша оцінка ng-app? jsfiddle.net/vwcbtzdg
Si8

Перший лише автоматично ініціалізований, інші мають ініціалізуватися вручну
Мано

0

Використовуйте angular.bootstrap(element, [modules], [config])для запуску програми AngularJS вручну (докладнішу інформацію див. У посібнику Bootstrap ).

Дивіться наступний приклад:

// 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
Додайте опис своєї відповіді на те, що ви розмістили
Абхінав Сінгх Маурія

1
Потрібні коментарі, що пояснюють, що відбувається! Хороша спроба!
Ерік Браун - Кал
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.