我有一个类似于此的Angular 1.3模块(使用controllerAs
需要父指令存在的指令):
angular.module('fooModule', [])
.controller('FooController', function ($scope) {
this.doSomething = function () {
// Accessing parentDirectiveCtrl via $scope
$scope.parentDirectiveCtrl();
};
})
.directive('fooDirective', function () {
return {
// Passing in parentDirectiveCtrl into $scope here
link: function link(scope, element, attrs, parentDirectiveCtrl) {
scope.parentDirectiveCtrl = parentDirectiveCtrl;
},
controller: 'FooController',
controllerAs: 'controller',
bindToController: true,
require: '^parentDirective'
};
});
我只是使用$scope
来传递parentDirectiveCtrl
,这看起来有点笨拙。
是否有另一种方法可以从指令的控制器访问require
-ed控制器而不使用链接功能?
答案 0 :(得分:3)
您必须使用link
函数来获取require
- ed控制器,但您不需要使用示波器将控制器的引用传递给您自己的控制器。而是将其直接传递给您自己的控制器:
.directive('fooDirective', function () {
return {
require: ["fooDirective", "^parentDirective"],
link: function link(scope, element, attrs, ctrls) {
var me = ctrls[0],
parent = ctrls[1];
me.parent = parent;
},
controller: function(){...},
};
});
但是要小心,因为控制器在链接之前运行,所以在控制器this.parent
内是undefined
,直到链接功能运行之后。如果您需要确切知道何时发生这种情况,您始终可以使用控制器功能将parentDirective
控制器传递给:
link: function link(scope, element, attrs, ctrls) {
//...
me.registerParent(parent);
},
controller: function(){
this.registerParent = function(parent){
//...
}
}
答案 1 :(得分:1)
有一种方法可以避免使用$scope
访问父控制器,但您必须使用link
函数。
Angular的文档says:
<强>需要强>
需要另一个指令并将其控制器作为第四个注入 链接函数的参数......
选项1
由于controllerAs
在控制器的scope
中创建了命名空间,您可以在link
函数中访问此命名空间,并将所需的控制器直接放在childDirective
的控制器上,而不是使用$scope
。然后代码看起来像这样。
angular.module('app', []).
controller('parentController', function() {
this.doSomething = function() {
alert('parent');
};
}).
controller('childController', function() {
this.click = function() {
this.parentDirectiveCtrl.doSomething();
}
}).
directive('parentDirective', function() {
return {
controller: 'parentController'
}
}).
directive('childDirective', function() {
return {
template: '<button ng-click="controller.click()">Click me</button>',
link: function link(scope, element, attrs, parentDirectiveCtrl) {
scope.controller.parentDirectiveCtrl = parentDirectiveCtrl;
},
controller: 'childController',
controllerAs: 'controller',
bindToController: true,
require: '^parentDirective'
}
});
<强> Plunker 强>:
http://plnkr.co/edit/YwakJATaeuvUV2RBDTGr?p=preview
选项2
我通常不会在我的指令中使用控制器,而是通过服务共享功能。如果您不需要使用父和子指令的隔离范围,只需将相同的服务注入其中,并将所有功能都用于服务。
angular.module('app', []).
service('srv', function() {
this.value = '';
this.doSomething = function(source) {
this.value = source;
}
}).
directive('parentDirective', ['srv', function(srv) {
return {
template: '<div>' +
'<span ng-click="srv.doSomething(\'parent\')">Parent {{srv.value}}</span>' +
'<span ng-transclude></span>' +
'</div>',
transclude: true,
link: function(scope) { scope.srv = srv; }
};
}]).
directive('childDirective', ['srv', function(srv) {
return {
template: '<button ng-click="srv.doSomething(\'child\')">Click me</button>',
link: function link(scope) { scope.srv = srv; }
}
}]);
<强> Plunker 强>
答案 2 :(得分:0)
好问题! Angular让你通过&#34; parent&#34;控制器。您已将其作为链接功能的参数。这是第四个参数。为简单起见,我将其命名为ctrl。您不需要scope.parentDirectiveCtrl = parentDirectiveCtrl行。
.directive('fooDirective', function () {
return {
// Passing in parentDirectiveCtrl into $scope here
link: function link(scope, element, attrs, ctrl) {
// What you had here is not required.
},
controller: 'FooController',
controllerAs: 'controller',
bindToController: true,
require: '^parentDirective'};});
现在在您的父控制器上有
this.doSomething=function().
您可以将此doSomething视为
ctrl.doSomething().