web-dev-qa-db-fra.com

$ emit ou $ broadcast un événement d'un contrôleur vers une directive AngularJS

Je veux pouvoir notifier une directive lorsqu'un événement se produit pour modifier ce que la directive affiche. Je sais que les directives ne s'exécutent qu'une seule fois, je me demande donc comment procéder. Je ne sais pas non plus si je dois utiliser $ emit ou $ broadcast, une directive est-elle un enfant du contrôleur?

Par exemple, dans mon contrôleur, j'ai:

$rootScope.$emit('PHOTO_UPLOADED', photo);

Et dans ma 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;
      });
    }
  };
}])

J'ai essayé de le faire mais rien ne s'est produit, la vignette n'a pas été mise à jour car la directive a déjà été exécutée.

21
user1876246

Utilisation $broadcast. Cela diffusera des événements aux enfants. Voici un exemple d'utilisation de la diffusion pour envoyer des données à une directive à partir d'un contrôleur parent:

http://jsfiddle.net/smaye81/q2hbnL5b/6/

25
sma

Dans votre contrôleur, faites:

$rootScope.$broadcast('PHOTO_UPLOADED', photo);

et dans votre directive, capturez l'événement diffusé via

  $rootScope.$on('PHOTO_UPLOADED', function(event, data) {
         thumbnail = data;
      });
6
raga

Vous devez vous assurer de passer $rootScope à votre directive afin qu'elle puisse être injectée:

.directive('photo', ['$rootScope', function($rootScope) {
// snip
}]);

Modifiez la première ligne de votre code à la précédente et cela devrait fonctionner correctement.

4
Mike Driver