我遵循以下模式,我需要从父指令调用子指令的API函数
以下是小提琴:http://jsfiddle.net/gauravsoni/qykbfvy0/2/
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl',function(){
})
myApp.directive('d1', function() {
return {
controller: function($scope,$element) {
console.log('d1 - ctrl');
// $scope.api.awesomeApi();
$scope.clicked = function(){
$scope.api.awesomeApi();
}
},
link: function(scope,ele,attr) {
//scope.api.awesomeApi();
console.log('d2 - link');
},
template:"This is D1<button ng-click='clicked()'>Clicked</button> <div d2 apifn='api'></div>"
}
});
myApp.directive('d2', function() {
return {
scope:{
apifn:"="
},
controller: function($scope,$element) {
console.log('d2 - ctrl');
$scope.isvisible = true;
function awesomeApiFn(){
console.log('api function is called');
}
$scope.apifn = {
awesomeApi:awesomeApiFn
}
},
link: function(scope,ele,attr) {
console.log('d2 - link');
},
template:'<div ng-if="isvisible"><p>Hello</p><h3>WORLD</h3><div>'
}
});
问题是当我在加载d1控制器期间调用$scope.api.awesomeApi()
时它显示未定义哪个是正确的,但是当我在d1的链接中调用awesomeApi()时它应该作为d1的链接工作在d2的链接之后被调用但它不起作用并且我再次未定义。
如何确保d1中的api函数仅在d2完成编译后调用?或者是否有一些更好的模式来揭示指令d2的API函数。
答案 0 :(得分:0)
考虑将d1控制器注入child指令并在链接阶段(example fiddle)添加api对象:
myApp.directive('d1', function() {
return {
controller: function($scope,$element) {
var self = this;
console.log('d1 - ctrl');
$scope.clicked = function(){
self.api.awesomeApi();
}
},
// ctrl.api has been set by child directive's link function
link: function(scope,ele,attr,ctrl) {
console.log('d1 - link');
ctrl.api.awesomeApi();
},
template:"This is D1<button ng-click='clicked()'>Clicked</button> <div d2></div>"
}
});
myApp.directive('d2', function() {
return {
// require both controllers
require: ['^d1', 'd2'],
controller: function($scope,$element) {
console.log('d2 - ctrl');
$scope.isvisible = true;
function awesomeApiFn(){
console.log('api function is called');
}
// put api object on d2 (this) controller
this.api = {
awesomeApi:awesomeApiFn
}
},
link: function(scope,ele,attr,ctrls) {
var d1Controller = ctrls[0];
var d2Controller = ctrls[1];
console.log('d2 - link');
// update d1Controller to have d2Controller api
d1Controller.api = d2Controller.api;
},
template:'<div ng-if="isvisible"><p>Hello</p><h3>WORLD</h3><div>'
}
});
我认为您遇到的问题是,由于来自隔离范围的2路绑定,$ scope.api对象直到另一个摘要周期才被修改。从父控制器到子控制器进行通信的另一个选择是$从父作用域广播事件。子范围将处理此问题并委托其api函数。为您的用例做最有意义的事情。如果d1和d2相互依赖,可能需要使用控制器注入(例如上面的例子)。如果你想让它们更松散地耦合,那么请选择事件。从您的示例中看,它们似乎属于一起(因为您正在访问两者之间的对象)。