我的AngularJS应用程序中有一个页面,我想在其中包含相同的html部分,但具有不同的变量。如果我在我的主html
中执行此操作:
<div id="div1" ng-include src="partials/toBeIncluded.html onload="var='A'">
<div id="div2" ng-include src="partials/toBeIncluded.html onload="var='B'">
toBeIncluded.html
看起来像
<div>{{var}}</div>
两个div
都看起来像
<div id="div1"><div>B</div></div>
<div id="div2"><div>B</div></div>
我想这与为ng-includes调用相同的onload
这一事实有关。那么如何将不同的变量发送到每个不同的包含?
答案 0 :(得分:39)
每次加载新部分时,传递给onload
的表达式都会计算。在这种情况下,您要将var
的值更改两次,以便在加载两个部分时,当前值将为B
您希望将不同的数据传递给每个部分/模板(底层的html文件是相同的)。为了实现这一点,正如Tiago所提到的,你可以用不同的控制器来做到这一点。例如,请考虑以下
<body ng-controller='MainCtrl'>
<div ng-include src='"toBeIncluded.html"' ng-controller='ctrlA' onload="hi()"></div>
<div ng-include src='"toBeIncluded.html"' ng-controller='ctrlB' onload="hi()"></div>
</body>
在这里,我们有两个部分,每个部分都有自己的范围,由自己的控制器(ctrlA
和ctrlB
)管理,两个子范围都是MainCtrl
。函数hi()
属于MainCtrl
的范围,将运行两次。
如果我们有以下控制器
app.controller('MainCtrl', function($scope) {
$scope.msg = "Hello from main controller";
$scope.hi= function(){console.log('hi');};
});
app.controller('ctrlA', function($scope) {
$scope.v = "Hello from controller A";
});
app.controller('ctrlB', function($scope) {
$scope.v = "Hello from controller B";
});
toBeIncluded.html
的内容是
<p>value of msg = {{msg}}</p>
<p>value of v = {{v}} </p>
生成的html将是以下几行
<p>value of msg = Hello from main controller</p>
<p>value of v = Hello from main controller A </p>
和
<p>value of msg = Hello from main controller</p>
<p>value of v = Hello from controller B </p>
答案 1 :(得分:26)
就像马克所说的那样,但是为了简化它并使其更加“在飞行中”是使用以下内容:
<div ng-repeat="name in ['John']" ng-include="'name-template.html'"></div>
<div ng-repeat="name in ['Jack']" ng-include="'name-template.html'"></div>
<script type="text/ng-template" id="name-template.html">
<div>The name is {{ name }}</div>
<script>
答案 2 :(得分:20)
在你对@jm-答案的评论中,你提到你想加载部分内部ng-repeat。为此,请在$ scope上创建一个数组,并在该数组上设置唯一值:
$scope.partialStuff = [ 'p1', 'p2', 'p3' ];
你偏爱中的某个地方:
{{partialVar}}
HTML:
<div ng-repeat="partialVar in partialStuff">
<div ng-include src="'partials/toBeIncluded.html'"></div>
</div>
答案 3 :(得分:10)
我可能错了,但使用指令会不会更好?
.directive('foobar', [function factory() {
return {
restrict: 'E',
replace: true,
templateUrl: '/toBeIncluded.html',
scope: {
"var": "="
}
};
}]);
和你的HTML
<div ng-repeat="var in data">
<foobar var="var"></foobar>
</div>
现在应该用模板替换foobar元素。每个人都拥有自己的范围。
答案 4 :(得分:1)
具体来说,ng-init和onload表达式在父范围内进行评估,而不是由nginclude创建的子范围。因此,您要在父作用域上为var
赋值两次,这两个值都是在编译和评估这些ng-includes内的内容之前发生的。创建每个子作用域时,它继承自父作用域,其中var ='B'。
答案 5 :(得分:1)
考虑你的部分内部有变量foo,
然后你会像这样传递foo:
<ng-include src="'partials/foo-part.html'" onLoad="foo='bar'"></ng-include>
为了获得更多浏览器兼容性,您可以像这样传递:
<div ng-include src="'partials/foo-part.html'" onLoad="foo='bar'"></div>
您也可以使用onInclude="foo='bar'"
代替onLoad
答案 6 :(得分:0)
所有ng-includes都没有调用相同的“onLoad”。最有可能的是,var设置为A,然后设置为B.事实上,它在两个包含中共享,因为它们位于相同的范围内。 'var'作为angularJS中的模型,取决于范围。
为了使您的部分具有单独的值,它们必须各自具有自己的范围。最简单的方法是设置一个控制器或指令,并将其分配给ng-include所在的Dom元素,并在该范围内设置你的值。
答案 7 :(得分:0)
我遇到了同样的问题,我找到了实现我想要的方法 当然它看起来不是很漂亮但仍然。
我使用了ng-repeat,这将创建一个新的范围,包括两个相同的模板,使用不同的值,如此(虚拟示例):
<script type="text/ng-template" id="mod-edito.html">
<div class="mod-edito__media">
<img ng-src="{{ edito.cover.src }}" />
</div>
</script>
<div>
<ng-include ng-repeat="edito in [edito_object]" src="'mod-edito.html'"></ng-include>
...
<ng-include ng-repeat="edito in [edito_other]" src="'mod-edito.html'"></ng-include>
</div>
这可以接受吗?我想是的。
答案 8 :(得分:0)
我正在寻找替代方案,我想要一个js对象将一些参数发送到包含的部分中。 {@ 3}}由@ denis-pshenov制作的This is the evolved version。您可以使用控制器来填充数据,也可以使用ng-init。
基本上,像这样,
var myApp = angular.module('myApp',[]);
myApp.controller('Controller', function($scope) {
$scope.ourData = [ { name : 'John', address : 'Paradise' } ];
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="Controller">
<div ng-repeat="data in ourData" ng-include="'partial.html'"></div>
<div ng-init="ourData2 = [ { name : 'Jack', address : 'Paradise' } ]" />
<div ng-repeat="data in ourData2" ng-include="'partial.html'"></div>
</div>
<script type="text/ng-template" id="partial.html">
<div>The name is {{ data.name }} and the address is {{ data.address }} </div>
</script>
&#13;
答案 9 :(得分:0)
有一种方法可以创建通用的可重用指令。
以下是我的一位同事提出的建议(灵感来自Knockout.js)。
指令:
(function () {
'use strict';
angular
.module('directives')
.directive('ngWith', ngWith);
function ngWith() {
return {
restrict: 'A',
replace: true,
scope: {
model: '=',
template: '@'
},
template: '<div data-ng-include="template"></div>',
};
}
})();
用法:
<div data-ng-with="" data-model="parentObj.childObj.whatEver" data-template='my-template.html'></div>
答案 10 :(得分:0)
如果您将部分纳入ng-repeat,您仍然可以访问父作用域的$ index。只需在部分内包含{{$ index}}。
答案 11 :(得分:0)
使用onload不是一个干净的解决方案,因为它会占用全局范围。如果你有更复杂的东西,它将开始失败。
Using a new directive instead of ng-include是一个更清洁的解决方案。
理想用法如下:
<div ng-include-template="partials/toBeIncluded.html" ng-include-variables="{ var: 'A' }"></div>
<div ng-include-template="partials/toBeIncluded.html" ng-include-variables="{ var: 'B' }"></div>
指令是:
.directive(
'ngIncludeTemplate'
() ->
{
templateUrl: (elem, attrs) -> attrs.ngIncludeTemplate
restrict: 'A'
scope: {
'ngIncludeVariables': '&'
}
link: (scope, elem, attrs) ->
vars = scope.ngIncludeVariables()
for key, value of vars
scope[key] = value
}
)
您可以看到该指令不使用全局范围。相反,它从ng-include-variables读取对象,并将这些成员添加到其自己的本地范围。
ng-include不是可重用的,因为它可以访问全局范围。这有点奇怪。
我希望这是你想要的;它干净而且通用。
答案 12 :(得分:0)
您可以参考单个值(如$scope.a = 'test'
)和$scope.a = {a.test};
等对象的特征,并使用不同的范围来定义可见区域。
来自ng-if文档。
请注意,使用ngIf删除元素时,其范围将被销毁,并在元素恢复时创建新范围。
Simpe解决方案是包含ng-if
并将静态标准定义为ng-init
指令。
<div ng-if="<any-true-expression>" ng-init="val='First'" ng-include="'html/common.html'"</div>
<div ng-if="<any-true-expression>" ng-init="val='Second'" ng-include="'html/common.html'"</div>
在这种情况下,它将显示不同的值,如
{{val}} shows >>
First
Second
此内容是静态的,因为val是对值的简单引用。
如果您希望拥有依赖于某些常见范围值的动态可更改页面,则需要销毁并重新创建使用指令ng-if
时创建的范围。像这样:
<div id="wrapper" ng-if="orders_client">
<div id="client-orders" ng-init="orders = orders_client" ng-include="'html/pages/parts/orders-view.html'"></div>
</div>
和
$scope.orders_client = null;
/*recreate content table*/
$timeout(function () {
$rootScope.general.showPreloader = false;
$scope.orders_client = $scope.baseData.clients[newClient];
}, 500);
在这种情况下,将销毁具有先前数据的范围,并将创建具有新数据的新范围。需要时间重建新范围 500ms 。如果存在更好的捕获,请写下。
答案 13 :(得分:0)
每次通过ng-if=true
加载局部时,都可以使用ng-include
强制使用新作用域。
您的代码如下
<div id="div1" ng-include src="partials/toBeIncluded.html onload="var='A'" ng-if="true">
<div id="div2" ng-include src="partials/toBeIncluded.html onload="var='B'" ng-if="true">
可以在此plunker
找到一个示例另一个答案引用了相同的想法here
答案 14 :(得分:-3)
只需将每个ng-include置于其自己的<div>
下,如下所示:
<div>
<div id="div1" ng-include src="partials/toBeIncluded.html onload="var='A'"/>
</div>
<div>
<div id="div2" ng-include src="partials/toBeIncluded.html onload="var='B'"/>
</div>
每个包含的HTML都会在自己的范围内拥有自己的var
。