如何在一页中定义两个角度应用程序/模块?


118

我正在尝试将两个有角度的应用程序/模块添加到一页。在下面的小提琴中,您可以看到始终只有html代码中引用的第一个模块可以正常工作,而第二个模块不能被angular识别。

在这个小提琴中,我们只能执行该doSearch2方法,而在这个小提琴中,仅该doSearch方法可以正常工作。

我正在寻找如何将两个角度模块正确放置到一页中的方法。

Answers:


123

每个HTML文档只能自动引导一个AngularJS应用程序。在文档中找到的第一个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文档只能使用一次。如果页面上只有一个应用程序,这实际上只是一条捷径,这是正常情况。
Mark Rajcok

1
有这个例子吗?我看到了简洁的boostrap api文档,但无法正常工作。我已经用谷歌搜索了一段时间,似乎没有一个单独的示例。此外,这在世界范围内将如何与路线配合使用?显然有一个碰撞问题。
罗伯特·克里斯蒂安

另外,我真的很喜欢使用ng-app的方式向其他开发人员确切显示页面的哪个部分由哪个模块控制。有没有办法在页面上使用标记来完成此操作?或至少在标记中有一些提示?
chrismarx 2013年

1
ng-app指令的前两段说明了一切-docs.angularjs.org/api/ng.directive:ngApp
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的窗口小部件的窗口小部件生成器)或检测页面是否已经有一个应用程序,并注入另一个应用程序作为第一个的依赖项?我刚刚在这里发布了我的问题并提供了我要完成的工作的更多详细信息。谢谢!
Daniel Bonnell'1

@ACIDSTEALTH AngularJS报告该元素已经被引导的事实意味着必须有某种方法可以知道-尽管该代码可能是AngularJS的内部代码。要找出答案,您可以引用未精简版的AngularJS和该错误的断点以查看if条件。从您可以从StackOverflow问题链接中得出的信息来看,这听起来像是要在运行时动态“注入”模块。如果是这样,您可能想看一下这篇文章:weblogs.asp.net/dwahlin/…–
Luis Perez,

嘿@LuisPerez,我检查了您的网站。我在机器上累了。angularJS没有检测到“ ng-modules” /“ ng-module”。我是否需要文件中包含的任何参考?
sujay kodamala '16

是的@sujaykodamala,ngModule并未内置在AngularJS中,这是我创建的指令。您可以从GitHub下载它。您可以在这里找到它:github.com/luisperezphd/ngModule
Luis Perez,

您好@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>

未捕获的错误:[$注射器:modulerr] errors.angularjs.org/1.3.14/$injector/... ... criptMinification%2Fbower_components%2Fangular%2Fangular.min.js%3A17%3A381)
Anandaraja_Srinivasan

您是否尝试过反转2个模块的顺序?(“ app”之前的“ otherModule”)因为我经常使用此解决方案,因此效果很好……
Monkey Monk

1
好 !我在提供的Javascript示例中看到一个错误。我认为现在是固定的!为了记录,我将在同一模块的2个地方使用setter语法……这显然是不允许的!:-)
Monkey Monk

我们打算这样做的方式
哈里·波什

9

您可以引导多个角度应用程序,但是:

1)您需要手动引导它们

2)您不应使用“文档”作为根,而应将包含角度接口的节点用于:

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

这样会很安全的。


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-appid已被使用。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.