Как определить два приложения / модуля angular на одной странице?

118

Я пытаюсь добавить на одну страницу два приложения / модуля angular. В скриптах ниже вы можете видеть, что всегда только первый модуль, на который есть ссылка в html-коде, будет работать правильно, тогда как второй не распознается angular.

В этой скрипке мы можем выполнять только doSearch2метод, тогда как в этой скрипкеdoSearch правильно работает только метод.

Ищу способ как правильно разместить два угловых модуля на одной странице.

Томас Креммель
источник

Ответы:

123

Только одно приложение AngularJS может быть автоматически загружено для каждого HTML-документа. Первый ngApp, найденный в документе, будет использоваться для определения корневого элемента для автоматической загрузки в качестве приложения. Чтобы запустить несколько приложений в документе HTML, вы должны вручную загрузить их, используя вместо этого angular.bootstrap. Приложения AngularJS не могут быть вложены друг в друга. - http://docs.angularjs.org/api/ng.directive:ngApp

Смотрите также

Марк Райкок
источник
@MarkRajcok Итак, это хорошая практика - иметь только один модуль на документ HTML? Пример «Подключите бэкэнд» на основной странице AngularJS устанавливает ng-app="project"и говорит, что «это позволяет вам иметь модули, которые запускаются в разных частях страницы», но в документе ngApp говорится, что «только одна директива может использоваться для каждого HTML-документа».
theblang
9
@mattblang, модули связаны с приложениями Angular, а не с документами HTML. Обычно вам нужно только одно приложение на страницу / документ, но если вы хотите запустить несколько приложений Angular (каждое из которых может использовать один или несколько модулей) на одной и той же странице / документе, вам необходимо вручную выполнить загрузку каждого из них - - не используйте ng-app(потому что это не сработает). ng-appможно использовать только один раз в документе HTML. Это действительно просто сокращение, если у вас есть только одно приложение на странице, что является нормальным случаем.
Марк Райкок
1
Есть такой пример? Я вижу краткую документацию по API Boostrap, но не могу заставить ее работать. Некоторое время я гуглил, и, похоже, нет ни одного рабочего примера. Кроме того, как вообще это будет работать с маршрутами? Очевидно, существует проблема столкновения.
Роберт Кристиан
Кроме того, мне очень нравится, как использование ng-app показывает другому разработчику, какая именно часть страницы контролируется каким модулем. Нет возможности использовать разметку на странице для этого? Или хотя бы намек в разметке?
chrismarx
1
Первые два абзаца директивы ng-app говорят сами за себя
simo
38

Я создал альтернативную директиву, которая не имеет ngAppограничений. Это называется 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/

По сути, это тот же код, который используется внутри AngularJS без ограничений.

Луис Перес
источник
luisperezphd: Я прочитал ваш пост в блоге. Есть ли способ вложить приложения (например, конструктор виджетов с загруженным виджетом AJAX) или определить, есть ли на странице уже приложение, и внедрить другое приложение в качестве зависимости от первого? Я только что разместил здесь свой вопрос с более подробной информацией о том, чего я пытаюсь достичь. Спасибо!
Дэниел Боннелл,
@ACIDSTEALTH Тот факт, что AngularJS сообщает, что элемент уже загрузился, означает, что должен быть какой-то способ узнать, хотя этот код может быть внутренним для AngularJS. Чтобы узнать, вы можете сослаться на унифицированную версию AngularJS и точку останова на этой ошибке, чтобы увидеть условие if. Из того, что я могу понять из вашей ссылки на вопрос на StackOverflow, похоже, что вы хотите динамически «внедрить» модуль во время выполнения. Если да, то, возможно, вам стоит взглянуть на эту статью: weblogs.asp.net/dwahlin/…
Луис Перес,
Привет, @LuisPerez, я проверил ваш сайт. Устал на своей машине. angularJS не обнаруживает "ng-modules" / "ng-module". Нужны ли мне ссылки в моем файле?
суджай кодамала
Да @sujaykodamala, ngModule не встроен в AngularJS, это директива, которую я создал. Вы можете скачать его с GitHub. Вы можете найти его здесь: github.com/luisperezphd/ngModule
Луис Перес,
Привет, @Luis Perez! Я проверял ваше сообщение в блоге, и они действительно потрясающие. Если у вас есть время, не могли бы вы проверить мой пост здесь, чтобы решить проблему - stackoverflow.com/questions/46952478/… . Спасибо.
user8512043
19

Почему вы хотите использовать несколько [ng-app]? Поскольку Angular возобновляется с использованием модулей, вы можете использовать приложение, использующее несколько зависимостей.

Javascript:

// setter syntax -> initializing other module for demonstration
angular.module('otherModule', []);

angular.module('app', ['otherModule'])
.controller('AppController', function () {
    // ...do something
});

// getter syntax
angular.module('otherModule')
.controller('OtherController', function () {
    // ...do something
});

HTML:

<div ng-app="app">
    <div ng-controller="AppController">...</div>
    <div ng-controller="OtherController">...</div>
</div>

РЕДАКТИРОВАТЬ

Имейте в виду, что если вы хотите использовать контроллер внутри контроллера, вы должны использовать синтаксис controllerAs, например:

<div ng-app="app">
    <div ng-controller="AppController as app">
        <div ng-controller="OtherController as other">...</div>
    </div>
</div>
Обезьяна-монах
источник
Uncaught Ошибка: [$ Инжектор: modulerr] errors.angularjs.org/1.3.14/$injector/... ... criptMinification% 2Fbower_components% 2Fangular% 2Fangular.min.js% 3A17% 3A381)
Anandaraja_Srinivasan
Вы пробовали инвертировать порядок двух модулей? ('OtherModule' перед 'app') Потому что я часто использую это решение, и оно отлично работает ...
Monkey Monk
1
Хорошо ! Я видел ошибку в приведенном мной примере Javascript. Думаю, сейчас это исправлено! Для записи я использовал синтаксис установщика в двух местах для одного и того же модуля ... что явно недопустимо! :-)
Monkey Monk
как мы
Гарри Бош
9

Вы можете загрузить несколько приложений angular, но:

1) Вам нужно вручную загрузить их

2) Вы должны использовать не «документ» в качестве корня, а узел, в котором содержится интерфейс angular:

var todoRootNode = jQuery('[ng-controller=TodoController]');
angular.bootstrap(todoRootNode, ['TodoApp']);

Это было бы безопасно.

Wouter
источник
3

Ручная загрузка обоих модулей будет работать. Посмотри на это

  <!-- IN HTML -->
  <div id="dvFirst">
    <div ng-controller="FirstController">
      <p>1: {{ desc }}</p>
    </div>
  </div>

  <div id="dvSecond">
    <div ng-controller="SecondController ">
      <p>2: {{ desc }}</p>
    </div>
  </div>



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

Вот ссылка на Plunker http://plnkr.co/edit/1SdZ4QpPfuHtdBjTKJIu?p=preview

ПРИМЕЧАНИЕ. В html нет ng-app. idвместо этого был использован.

Хари Дас
источник
0

Я сделал POC для приложения Angular, используя несколько модулей и выходов маршрутизатора для вложения вложенных приложений в одностраничное приложение. Вы можете получить исходный код по адресу: https://github.com/AhmedBahet/ng-sub-apps

Надеюсь, это поможет

abahet
источник