不同的ng-include在同一页上:如何向每个发送不同的variables?
我在我的AngularJS应用程序中有一个页面,我想包含相同的html部分,但具有不同的variables。 如果我在我的主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
被调用的事实有关。 那么我如何向每个不同的包含发送不同的variables呢?
传递给onload
的expression式会在每次加载新的部分时进行评估。 在这种情况下,你正在改变var
的值两次,所以当两个partials被加载时,当前的值将是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
)pipe理,都是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>
例如: http : //plnkr.co/edit/xeloFM?p=preview
就像马克说的,但为了简化它,让它更“dynamic”是使用以下内容:
<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>
示例: http : //jsfiddle.net/Cndc6/4/
在你对@ jm-的回答的评论中,你提到你想加载你的部分内部ng-repeat。 为此,请在$ scope上创build一个数组,并在该数组上设置唯一值:
$scope.partialStuff = [ 'p1', 'p2', 'p3' ];
某处在你的部分:
{{partialVar}}
HTML:
<div ng-repeat="partialVar in partialStuff"> <div ng-include src="'partials/toBeIncluded.html'"></div> </div>
小提琴 。
我可能是错的,但使用指令不是更好吗?
.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元素应该被replace为你的模板。 每个人都有自己的范围。
具体而言,ng-init和onloadexpression式在父范围内进行计算,而不是由nginclude创build的子范围。 因此,你将赋值给父范围的var
两次,这两个都是在ng-includes内部的内容被加载之前进行编译和计算的。 当创build每个子作用域时,它都从父作用域inheritance,其中var ='B'。
考虑你在你的部分里面有variablesfoo,
那么你会像这样传递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
plnkr.co/edit/GHRNyAMBKLvgtf3NFSRu?p=info
同样的“onLoad”不会被调用所有的ng-includes。 最有可能的是,var被设置为A,然后被设置为B.事情是,它在两个包含之间被共享,因为它们在相同的范围内。 'var'作为angularJS中的一个模型,是依赖于范围的。
为了让你的部分有独立的价值,他们必须各自有自己的范围。 最简单的方法是build立一个控制器或指令,并将其分配给ng-include所在的Dom元素,并将该值设置在该范围内。
我有同样的问题,我find了一种方法来实现我想要的,当然它看起来不漂亮,但仍然。
我使用了ng-repeat,它会创build一个新的作用域,将两个不同的值包含在同一个模板中,如下所示(虚拟示例):
<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>
这可以接受吗? 我猜是这样。
我正在寻找替代品,我想要一个JS对象发送一些参数到包含的部分。 这是 @ denis-pshenov所做的演变版本 。 您可以使用控制器来填充数据,或者使用ng-init。
基本上,这样的事情,
var myApp = angular.module('myApp',[]); myApp.controller('Controller', function($scope) { $scope.ourData = [ { name : 'John', address : 'Paradise' } ]; });
<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>
有一种方法可以创build一个通用的可重用指令。
这是我的一个同事想出来的(由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>
如果您在ng-repeat中包含部分内容,您仍然可以访问父范围的$ index。 只要在部分中包含{{$ index}}。
使用onload不是一个干净的解决scheme,因为它抛弃了全球范围。 如果你有更复杂的东西,它会开始失败。
使用新的指令而不是ng-include是一个更清洁的解决scheme。
理想的用法如下所示:
<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不是可重用的,因为它可以访问全局范围。 这有点奇怪。
我希望这是你想要的; 它是干净的和通用的。
把每个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
。