使用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仅使用常规控制器实例化,就没有机会注入任何东西。
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){ });
矮人