Different ng-include's on the same page: how to send different variables to each?
我的AngularJS应用程序中有一个页面,我希望在其中包含相同的HTML部分,但变量不同。如果我在我的主
1 |
而
1 | {{var}} |
两个
1 2 | B B |
我想这是因为同样的
每次加载新的分部时,传递给
您希望将不同的数据传递给每个部分/模板(基础HTML文件相同)。要实现这一点,正如Tiago提到的,您可以使用不同的控制器。例如,考虑以下内容
1 2 3 4 | <body ng-controller='MainCtrl'> </body> |
这里,我们有两个部分,每个部分有自己的范围,由自己的控制器(
如果我们有以下控制器
1 2 3 4 5 6 7 8 9 10 11 12 | 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"; }); |
1 2 3 4 5 6 | <p> value of msg = {{msg}} </p> <p> value of v = {{v}} </p> |
生成的HTML将是以下几行中的某个内容
1 2 3 4 5 6 | <p> value of msg = Hello from main controller </p> <p> value of v = Hello from main controller A </p> |
和
1 2 3 4 5 6 | <p> value of msg = Hello from main controller </p> <p> value of v = Hello from controller B </p> |
例如:http://plnkr.co/edit/xelofm?P=预览
正如马克所说的,但要简化一点,使其更"即时"是使用以下方法:
1 2 | <script type="text/ng-template" id="name-template.html"> The name is {{ name }} |
示例:http://jsfiddle.net/cndc6/4/
在您对@jm-答案的评论中,您提到要在ng repeat中加载部分内容。为此,请在$scope上创建一个数组,并在该数组上设置唯一值:
1 | $scope.partialStuff = [ 'p1', 'p2', 'p3' ]; |
在你的部分:
1 | {{partialVar}} |
HTML:
1 |
小提琴。
我可能是错的,但使用指令不是更好吗?
1 2 3 4 5 6 7 8 9 10 | .directive('foobar', [function factory() { return { restrict: 'E', replace: true, templateUrl: '/toBeIncluded.html', scope: { "var":"=" } }; }]); |
还有你的HTML
1 | <foobar var="var"></foobar> |
现在应该用模板替换foobar元素。每个都有自己的范围。
假设你的部分中有变量foo,
然后你会像这样通过foo:
1 | <ng-include src="'partials/foo-part.html'" onLoad="foo='bar'"></ng-include> |
为了获得更多的浏览器兼容性,您可以这样传递它:
1 |
你也可以用
plnkr.co/edit/ghrnyambklvgtf3nfsru?P=信息
具体来说,ng init和onload表达式是在父作用域中计算的,而不是由nginclude创建的子作用域。因此,您要在父作用域上为
您可以参考特性单值(如
来自ng if文档。
Note that when an element is removed using ngIf its scope is destroyed and a new scope is created when the element is restored.
简单的解决方案是将
1 2 3 | " ng-init="val='First'" ng-include="'html/common.html'" " ng-init="val='Second'" ng-include="'html/common.html'" |
在这种情况下,它将以不同的值显示,如
1 2 3 | {{val}} shows >> First Second |
此内容是静态的,因为val是对值的简单引用。
如果您希望具有动态可更改的页面,这取决于一些公共范围值,则需要销毁并重新创建在使用指令
1 |
和
1 2 3 4 5 6 | $scope.orders_client = null; /*recreate content table*/ $timeout(function () { $rootScope.general.showPreloader = false; $scope.orders_client = $scope.baseData.clients[newClient]; }, 500); |
在这种情况下,将销毁具有以前数据的作用域,并创建具有新数据的新作用域。需要时间重新创建新的作用域500ms。如果存在更好的捕获,请写入。
使用onload不是一个干净的解决方案,因为它会破坏全局范围。如果你有更复杂的事情,它就会开始失败。
使用新的指令而不是ng include是一个更干净的解决方案。
理想用法如下:
1 |
指令是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | .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变量,并将这些成员添加到自己的本地范围中。
ng include没有那么可重用,因为它可以访问全局范围。有点奇怪。
我希望这是你想要的,它是干净的,通用的。
只是一个提示,如果在ng repeat中包含部分内容,您仍然可以访问父作用域的$index。只需在部分中包含$index。
有一种方法可以创建通用的可重用指令。
这是我的一个同事想出的(灵感来自knockout.js)。
指令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | (function () { 'use strict'; angular .module('directives') .directive('ngWith', ngWith); function ngWith() { return { restrict: 'A', replace: true, scope: { model: '=', template: '@' }, template: '', }; } })(); |
用途:
1 |
我在寻找一个替代方法,我想要一个JS对象向包含的部分发送一些参数。这是@denis pshenov制作的版本的进化版本。您可以使用控制器来填充数据,或者使用ng init。
基本上,像这样,
1 2 3 4 5 | var myApp = angular.module('myApp',[]); myApp.controller('Controller', function($scope) { $scope.ourData = [ { name : 'John', address : 'Paradise' } ]; }); |
1 2 3 4 5 6 7 8 9 10 11 12 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"> <script type="text/ng-template" id="partial.html"> The name is {{ data.name }} and the address is {{ data.address }} |
我也遇到了同样的问题,我找到了一种方法来实现我想要的当然,它看起来不太漂亮,但仍然很漂亮。
我使用了ng repeat,它将创建一个新的范围来包含非常相同的模板,两次使用不同的值,如so(虚拟示例):
1 2 3 4 5 6 7 8 9 10 | <script type="text/ng-template" id="mod-edito.html"> <img ng-src="{{ edito.cover.src }}" /> <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> |
可以接受吗?我想是的。
同样的"onload"并不能用于所有ng-include。很可能,var被设置为a,然后设置为b。问题是,它在两个includes之间被共享,因为它们在同一个范围内。‘var’,作为AngularJS中的一个模型,取决于作用域。
为了使分区具有单独的值,它们必须各自具有自己的作用域。最简单的方法是设置控制器或指令,并将其分配给包含ng的dom元素,然后在该范围内设置值。
只需将每个NG包括在其自身的
1 |
然后,每个包含的HTML都将在其自己的范围内拥有自己的