我有(以下)html:
<div ng-controller="MyController">
<my-sub-directive></my-sub-directive>
</div>
控制器的外观并不重要:
app.controller("MyController", function($scope) {
$scope.foo = "bar";
})
我的指令如下:
function mySubDirective() {
return {
restrict: "E",
templateUrl:"aTemplate.html",
require: "^MyController",
link: function($scope, element) {
}
};
}
app.directive("mySubDirective", mySubDirective);
在文档中,他们总是在require
- 属性中指定另一个指令,但它表示这意味着您需要控制器。所以我想尝试这个解决方案。但是我收到了错误
&#34;控制器&#39; MyController&#39;,指令&#39; mySubDirective&#39;所要求的,无法找到&#34;。
如果由ng-controller设置控制器,是否不能要求指令中的控制器?
答案 0 :(得分:5)
你只能这样做:
require: "^ngController"
所以,你不能比那更具体,即你不能按名称要求"MainCtrl"
或"MyController"
,但它会让你获得控制器实例: / p>
.controller("SomeController", function(){
this.doSomething = function(){
//
};
})
.directive("foo", function(){
return {
require: "?^ngController",
link: function(scope, element, attrs, ctrl){
if (ctrl && ctrl.doSomething){
ctrl.doSomething();
}
}
}
});
<div ng-controller="SomeController">
<foo></foo>
</div>
但是,我不认为这是一个很好的方法,因为它使指令非常依赖使用。您可以按照注释中的建议直接传递控制器实例 - 它使它更明确:
<div ng-controller="SomeController as ctrl">
<foo ctrl="ctrl"></foo>
</div>
但它仍然是一个过于通用的对象,很容易被你的指令用户误用。
相反,公开一个定义良好的API(通过属性)并将引用传递给控制器中定义的函数/属性:
<div ng-controller="SomeController as ctrl">
<foo do="ctrl.doSomething()"></foo>
</div>
答案 1 :(得分:0)
您可以在指令链接功能中使用element.controller()
来测试ngController
指定的最近控制器。这种方法的局限在于它不会告诉你它是哪个控制器。可能有几种方法可以做到,但我选择命名控制器构造函数,并在范围内公开它,因此您可以使用instanceof
// Deliberately not adding to global scope
(function() {
var app = angular.module('my-app', []);
// Exposed in so can do "instanceof" in directive
function MyController($scope) {}
app.controller('MyController', MyController);
app.directive("foo", function(){
return {
link: function($scope, $element){
var controller = $element.controller();
// True or false depending on whether the closest
// ngController is a MyController
console.log(controller instanceof MyController);
}
};
})
})();
您可以在http://plnkr.co/edit/AVmr7Eb7dQD70Mpmhpjm?p=preview
看到这一点但是,如果您嵌套了ngController
s,并且您想要测试一个不一定是最接近的那个,那么这项工作就不会起作用。为此,您可以定义一个递归函数来遍历DOM树:
app.directive("foo", function(){
function getAncestorController(element, controllerConstructor) {
var controller = element.controller();
if (controller instanceof controllerConstructor) {
return controller;
} else if (element.parent().length) {
return getAncestorController(element.parent(), controllerConstructor);
} else {
return void(0); // undefined
}
}
return {
link: function(scope, element){
var controller = getAncestorController(element, MyController);
// The ancestor controller instance, or undefined
console.log(controller);
}
};
})
您可以在http://plnkr.co/edit/xM5or4skle62Y9UPKfwG?p=preview
看到这一点供参考docs表示controller
函数可用于查找ngController
指定的控制器:
默认情况下,检索与ngController指令关联的控制器