user1876246
user1876246

Reputation: 1229

$emit or $broadcast an event from a controller to a directive AngularJS

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

Answers (3)

raga
raga

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

sma
sma

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

Mike Driver
Mike Driver

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

Related Questions