Reputation: 1229
I want to be able to notify a directive when an event happens to change what the directive displays. I know that directives only run once, so I am wondering how I would go about doing this. I am also not sure if I should use $emit or $broadcast, is a directive a child of the controller?
For example, in my controller I have:
$rootScope.$emit('PHOTO_UPLOADED', photo);
And in my directive:
.directive('photo', [function () {
return {
restrict: 'EA',
scope: {user: '='},
replace: true,
template: '<div id="{{user.id}}"></div>',
link: function ($scope, element, attrs) {
var thumbnail = ($scope.user && $scope.user.image)
? $scope.user.image
: '/default.png';
element.css('background-image', 'url(' + thumbnail + ')');
$rootScope.$on('PHOTO_UPLOADED', function(event, data) {
thumbnail = data;
});
}
};
}])
I tried to do this but nothing happened, the thumbnail was not updated because the directive already ran.
Upvotes: 22
Views: 21611
Reputation: 937
In your controller do:
$rootScope.$broadcast('PHOTO_UPLOADED', photo);
and in your directive, catch the broadcast event via
$rootScope.$on('PHOTO_UPLOADED', function(event, data) {
thumbnail = data;
});
Upvotes: 7
Reputation: 9597
Use $broadcast
. That will broadcast events to child scopes. Here is an example of using broadcast to send data to a directive from a parent controller:
http://jsfiddle.net/smaye81/q2hbnL5b/6/
Upvotes: 26
Reputation: 8511
You need to make sure to pass $rootScope
to your directive so it can be injected:
.directive('photo', ['$rootScope', function($rootScope) {
// snip
}]);
Modify you code's first line to the above and it should work fine.
Upvotes: 4