我试图动态分配控制器像这样包含的模板:
<section ng-repeat="panel in panels">
<div ng-include="'path/to/file.html'" ng-controller="{{panel}}"></div>
</section>
但是,角抱怨{{panel}}
是不确定的。
我猜测, {{panel}}
尚未确定(因为我可以附和了{{panel}}
在模板中)。
我见过很多人树立榜样ng-controller
等于一个变量,像这样: ng-controller="template.ctrlr"
。 但是,如果没有创建重复concurrant循环,我无法弄清楚如何让价值{{panel}}
可用时ng-controller
需要它。
PS我也试着设置ng-controller="{{panel}}"
在我的模板(认为它必须那么已经解决),但没有骰子。
你的问题是,NG-控制器应指向控制器本身,没有与控制器的名字只是字符串。
所以,你可能要定义$ scope.sidepanels与指针控制器,这样的事情,也许阵:
$scope.sidepanels = [Alerts, Subscriptions];
这里是JS提琴工作实例http://jsfiddle.net/ADukg/1559/
不过,我觉得很奇怪这一切的情况下,您可能要设置控制器在ngRepeat。
动态地设置在一个模板控制器,它有助于必须连接到控制器的构造函数的引用。 对于控制器的构造函数是你传递给功能controller()
角的方法模块API 。
有了这个帮助,因为如果传递给字符串ngController
指令不是注册的控制方的名称,然后ngController
将字符串作为表达对目前的范围进行评估。 这个范围表达需要评估到控制器构造函数 。
例如,假设角相遇在模板以下几点:
ng-controller="myController"
如果与名字没有控制器myController
注册,然后将角度看$scope.myController
当前包含控制器。 如果该键在存在范围和对应的值是控制器的构造 ,则控制器将被使用。
这在中提到ngController
文档中其参数值的描述:“全局可访问的构造函数,或在当前范围的计算结果为一个构造函数表达式的名称。” 在角源代码代码的注释中详细阐明了这一点, 在这里src/ng/controller.js
。
默认情况下,角不会很容易地访问连接到控制器的构造。 这是因为当你注册使用一个控制器controller()
角的方法模块API ,它隐藏你通过它在一个私有变量的构造。 你可以在这里看到$ ControllerProvider源代码 。 (该controllers
在这个代码变量是变量私人到$ControllerProvider
。)
我对这个问题的解决方案是创建一个名为通用助手服务registerController
登记控制器。 注册控制器时,该服务公开两个控制器和控制器构造函数。 这允许控制器两者在正常的方式,动态地使用。
下面是代码,我写了registerController
做这个服务:
var appServices = angular.module('app.services', []);
// Define a registerController service that creates a new controller
// in the usual way. In addition, the service registers the
// controller's constructor as a service. This allows the controller
// to be set dynamically within a template.
appServices.config(['$controllerProvider', '$injector', '$provide',
function ($controllerProvider, $injector, $provide) {
$provide.factory('registerController',
function registerControllerFactory() {
// Params:
// constructor: controller constructor function, optionally
// in the annotated array form.
return function registerController(name, constructor) {
// Register the controller constructor as a service.
$provide.factory(name + 'Factory', function () {
return constructor;
});
// Register the controller itself.
$controllerProvider.register(name, constructor);
};
});
}]);
下面是使用该服务来注册的控制器的一个示例:
appServices.run(['registerController',
function (registerController) {
registerController('testCtrl', ['$scope',
function testCtrl($scope) {
$scope.foo = 'bar';
}]);
}]);
上面的代码注册名称下的控制器testCtrl
,这也暴露了控制器的构造函数的调用的服务testCtrlFactory
。
现在,你可以在模板无论是在平时的fashion--使用控制器
ng-controller="testCtrl"
或dynamically--
ng-controller="templateController"
对于后者的工作,你必须在你当前范围如下:
$scope.templateController = testCtrlFactory
我相信你,因为你定义这样的(就像我以前做)你的控制器有这个问题:
app.controller('ControllerX', function() {
// your controller implementation
});
如果是这样的话,你不能简单地用引用ControllerX
因为控制器实现(或“类”,如果你要称呼它)是不是在全球范围内(而不是将其存储在应用$controllerProvider
)。
我建议你使用模板,而不是动态分配控制的引用(甚至是手动创建)。
控制器
var app = angular.module('app', []);
app.controller('Ctrl', function($scope, $controller) {
$scope.panels = [{template: 'panel1.html'}, {template: 'panel2.html'}];
});
app.controller("Panel1Ctrl", function($scope) {
$scope.id = 1;
});
app.controller("Panel2Ctrl", function($scope) {
$scope.id = 2;
});
模板(嘲笑)
<!-- panel1.html -->
<script type="text/ng-template" id="panel1.html">
<div ng-controller="Panel1Ctrl">
Content of panel {{id}}
</div>
</script>
<!-- panel2.html -->
<script type="text/ng-template" id="panel2.html">
<div ng-controller="Panel2Ctrl">
Content of panel {{id}}
</div>
</script>
视图
<div ng-controller="Ctrl">
<div ng-repeat="panel in panels">
<div ng-include src="panel.template"></div>
</div>
</div>
的jsfiddle: http://jsfiddle.net/Xn4H8/
另一种方法是不使用NG-重复,而是一个指令,它们编成存在。
HTML
<mysections></mysections>
指示
angular.module('app.directives', [])
.directive('mysections', ['$compile', function(compile){
return {
restrict: 'E',
link: function(scope, element, attrs) {
for(var i=0; i<panels.length; i++) {
var template = '<section><div ng-include="path/to/file.html" ng-controller="'+panels[i]+'"></div></section>';
var cTemplate = compile(template)(scope);
element.append(cTemplate);
}
}
}
}]);
好吧,我觉得这里最简单的解决办法是在你的文件的模板明确定义控制器。 比方说u有一个数组:
$scope.widgets = [
{templateUrl: 'templates/widgets/aWidget.html'},
{templateUrl: 'templates/widgets/bWidget.html'},
];
然后在你的HTML文件:
<div ng-repeat="widget in widgets">
<div ng-include="widget.templateUrl"></div>
</div>
而解决方案aWidget.html:
<div ng-controller="aWidgetCtrl">
aWidget
</div>
bWidget.html:
<div ng-controller="bWidgetCtrl">
bWidget
</div>
就那么简单! 你只要在你的模板定义控制器名称。 既然你定义控制器为bmleite说:
app.controller('ControllerX', function() {
// your controller implementation
});
那么这是我能想出的最好的解决方法。 这里唯一的问题是,如果u有像50个控制器,日子会把你必须明确地定义他们每个模板,但我猜ü了,因为你有一个NG重复与控制器通过手工设置为做到这一点呢。