使用ui.router,我们有一个状态控制器:
controller('widget',function($repository,$stateParams){ $scope.widget = $repository.get($stateParams.id); })
注册时间:
.state('widget',controller: 'widget',template: '/widgetTemplate.html'
我们遇到了一个案例,我们希望将此控制器作为模板的一部分重用:
<div ng-controller="widget" ng-include="/widgetTemplate.html"></div>
但似乎没有一种简单的方法可以使用正确的ID注入模拟的$stateParams对象.就像是:
<div ng-controller="widget" ng-inject="{$stateParams: {id: 1234}}" ng-include="/widgetTemplate.html"></div>
除了编写一个自定义指令来增强ng-controller或重构我们的代码以利用继承的作用域之外,是否有任何开箱即用的方法可以做到这一点?
我不相信有一种开箱即用的方式. ng-controller只使用普通的控制器实例化,没有机会注入任何东西.
但这是一个有趣的“功能”,实际上可以通过自定义指令相对简单地构建.
这是一个说明性的例子(免责声明:它绝对没有在晦涩的场景下测试):
.directive("ngInject",function($parse,$interpolate,$controller,$compile) { return { terminal: true,transclude: true,priority: 510,link: function(scope,element,attrs,ctrls,transclude) { if (!attrs.ngController) { element.removeAttr("ng-inject"); $compile(element)(scope); return; } var controllerName = attrs.ngController; var newScope = scope.$new(false); var locals = $parse(attrs.ngInject)(scope); locals.$scope = newScope; var controller = $controller(controllerName,locals); element.data("ngControllerController",controller); element.removeAttr("ng-inject").removeAttr("ng-controller"); $compile(element)(newScope); transclude(newScope,function(clone){ element.append(clone); }); // restore to hide tracks element.attr("ng-controller",controllerName); } }; });
用法如您所述:
<div ng-controller="MainCtrl"> {{name}} <div ng-controller="SecondCtrl" ng-inject="{foo: name,bar: 'bar'}"> </div> </div>
当然,控制器可以注入以下变量:
.controller("SecondCtrl",function($scope,foo,bar){ });