Reputation: 165
I have custom directives like this:
<fold fold-name="Musique et sons">
<sound-button height=60 song-name="Why Make..."></sound-button>
</fold>
fold directive has such template:
<button class="fold" ng-click="showMe = !showMe">{{foldName}} ({{nb}})</button>
<div class="fold" ng-transclude ng-show="showMe"></div>
In the sound-button controller, I have to do this:
$scope.$parent.$$prevSibling.$emit('foldstop')
If I want the controller to receive the event:
$scope.$on 'foldplay', (sender, evt) ->
What's happening: creates 3 scopes :
<fold> Scope
<ng-transclude scope> which has no model, thus no controller.
<sound-button scope>
In sound-button directive, $scope.$emit would hit the ng-transclude scope which is a sibling of the scope I want to hit.
So I'm using $scope.$parent.$prevSibling to hit the right controller. It works, but is there a better way ?
Thanks !
Upvotes: 1
Views: 1637
Reputation: 48972
You could try require
if your directives are related.
app.directive('soundButton', function() {
return {
restrict: 'E',
scope: {
songName: '@'
},
require:"^fold",
link : function (scope,element,attrs,foldController){//inject fold controller
foldController.callFold("message"); //use the controller to communicate
}
};
});
app.directive('fold', function() {
return {
restrict: 'E',
scope: {
foldName: '@'
},
templateUrl: 'fold.html',
transclude:true,
controller:function(){ //declare the controller to be used by child directives.
this.callFold = function (message){
alert(message);
}
}
};
});
You cannot use $scope.$emit
because your directives' scopes don't have parent/child relationship. You could refer to this discussion for more information.
Update:
If your directives are not related and you need to have parent/child relationship, you could try custom transclusion:
app.directive('fold', function() {
return {
restrict: 'E',
scope: {
foldName: '@'
},
templateUrl: 'fold.html',
transclude:true,
compile: function (element, attr, linker) {
return {
pre: function (scope, element, attr) {
linker(scope, function(clone){ //bind the scope your self
element.children().eq(1).append(clone); // add to DOM
});
},
post: function postLink(scope, iElement, iAttrs) {
scope.$on("foldplay",function(event,data){
alert(data);
});
}
};
}
};
});
DEMO (click on the button and then click on the shown text)
Upvotes: 2