Reputation: 29159
Normally we give a child-directive a callback function which it can call if something happens. In my case, its the other way around; I would like to inform the directive about something. I'm still using angular 1.4 (but soon I'll move to 1.5 and eventually to 2). With this in mind I would like to avoid things like $watch
and $broadcast
.
So, I think there are two solution: 1) use a service and 2) bind a callback function from the child to the parent
1) Although this might be the preferred solution I see two problems
a) A whole service for such a simple task
b) you'll need $watch
to detect the change
2) Well, this solution sounds super easy, but it seems to be more complicated than I expected or maybe it is not even possible :(
Here is my test code:
<button ng-click="mycontroller.callback()">Click me</button>
<bar-foo activate-me="mycontroller.callback"></bar-foo>
So, mycontroller
doesn't have a function callback
, but the directive bar-foo
does
angular.module('HelloApp')
.directive('barFoo', function () {
return {
restrict: 'E',
scope:{
activateMe: '='
},
controller: function ($scope) {
$scope.activateMe = function () {
this.activated = true
}
},
template: '<p ng-if="activated">Activated</p>'
}
});
Is what I'm trying possible ? or should I accept that services
are the one and only way to tackle this or is there more ?
Upvotes: 1
Views: 1202
Reputation: 193291
I think you are thinking too hard here. While it is possible to give outer controller a function to call and notify directive directly (which you should not do), much more straightforward and and natural approach is to use input binding. In your case it will be as simple as:
angular.module('HelloApp', []).controller("MyCtrl", function($scope) {
this.callBarFoo = function() {
this.callback = true;
}
});
angular.module('HelloApp')
.directive('barFoo', function() {
return {
restrict: 'E',
scope: {
activateMe: '='
},
controller: function($scope) {
},
template: '<p ng-if="activateMe">Activated</p>'
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<div ng-app="HelloApp" data-ng-controller="MyCtrl as mycontroller">
<button ng-click="mycontroller.callBarFoo()">Click me</button>
<bar-foo activate-me="mycontroller.callback"></bar-foo>
</div>
In general, controller is supposed to let directive know about data whenever it is appropriate. This is recommended data flow direction: from controller -> into directive. Directive should never ask for data itself. It's controller who decides when and what to pass into directive. When directive might need some data - then two-way binding can be used.
Related reading I put together here.
Upvotes: 1
Reputation: 1300
The one alternative way I know it is to attach some id to directive root element . Then from your controller you can do so .
angular.element(document.getElementById('the-id')).scope().directiveFunction(args);
Upvotes: 0