AngularJS 页面内的多个 ng-app
Posted
技术标签:
【中文标题】AngularJS 页面内的多个 ng-app【英文标题】:AngularJS Multiple ng-app within a page 【发布时间】: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>
【问题讨论】:
这可能会有所帮助:***.com/questions/12860595/… 谢谢切尔尼夫。这非常有帮助,我使用您提供的链接解决了问题。请您还提供有关如何使用 console.log 在视图/模板中转储控制器的信息 console.log 不起作用。 欢迎您。请注意,您已经在视图中执行“控制台”,这:item.product_name
实际上“打印”了模型中的值
为一个webapp创建多个app有什么问题吗?我有这个项目,每个 html 页面都有自己的应用程序,我想知道性能是否会受到影响?
虽然每页可以引导多个 AngularJS 应用程序,但我们不会主动针对这种情况进行测试。您可能会遇到问题,尤其是对于复杂的应用程序,因此建议您谨慎行事。见AngularJS Developer Guide - Bootstrap。
【参考方案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 上更新。
-
可以在 RootModule 中注入第二个模块。
在 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>
#titrecolor: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"]);
);
【讨论】:
V1.6 已弃用: 使用angular.element(callback)
而不是 angular.element(document).ready(callback))
。见AngularJS angular.element API Reference。还有github.com/angular/angular.js/commit/…【参考方案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>
【讨论】:
你可以创建一个指令来代替***.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。见***.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()
。
【讨论】:
以上是关于AngularJS 页面内的多个 ng-app的主要内容,如果未能解决你的问题,请参考以下文章
在 AngularJS 页面上显示多个 Oracle SQL 查询结果
在单个页面上制作一个应用程序的多个不同副本(AngularJS)