web-dev-qa-db-fra.com

Comment créer un événement personnalisé dans un service AngularJs

Je travaille sur un projet AngularJs. J'ai un service qui définit et supprime des événements sur certains boutons. Ce service est utilisé par un autre service que je ne souhaite pas interagir directement avec les boutons. Cependant, je voudrais qu'un événement de clic de bouton soit filtré dans le premier service et géré dans le second. Comme je ne veux pas que le deuxième service soit au courant des boutons, je pense que je devrai créer un événement personnalisé dans le premier service. Comment puis-je créer un événement personnalisé et le déclencher lorsqu'un bouton est cliqué?

Merci d'avance.

35
rmg.n3t

Si vous souhaitez envoyer un événement entre services/directives, utilisez broadcast:

$rootScope.$broadcast('buttonPressedEvent');

Et recevez-le comme ceci:

$rootScope.$on('buttonPressedEvent', function () {
             //do stuff
        })
82
Chancho

Toute intégration basée sur la portée mondiale nuirait à l'espace de noms et pourrait entraîner de terribles effets secondaires dans les applications de moyenne et grande taille. Je recommande une solution un peu plus compliquée mais certainement plus propre, en utilisant le service proxy.

1. Créer un service proxy

angular.module('app').service('userClickingHelper', [
  function() {
    var listeners = [];
    return {
      click: function(args) {
        listeners.forEach(function(cb) {
          cb(args);
        });
      },
      register: function(callback) {
        listeners.Push(callback);
      }
    };
  }
]);

2. Créer une directive de bouton qui utilise userClickingHelper comme dépendance.

angular.module('app').directive('onDistributedClick', ['userClickingHelper', function (userClickingHelper) {
    return {
        restrict: 'A',
        link: function (scope, element) {
            element.on('click', userClickingHelper.click);
        }
    };
}]);

. Enregistrez votre service indépendant avec l'aide du proxy.

angular.module('app').service('myUnrelatedService', [function (userClickingHelper) {
    userClickingHelper.register(function(){
        console.log("The button is clicked somewhere");
    });
}]);

Le résultat est une portée isolée de distribution d'événements, mais ni la directive, ni le service ne se connaissent. Il est également plus facile de faire des tests unitaires.

J'utilise une solution similaire pour le modal de "chargement" accessible à l'échelle mondiale afin de pouvoir résumer la façon dont un contrôleur/service dit "l'utilisateur ne doit pas cliquer ou quoi que ce soit en ce moment".

34
Mano Kovacs

Vous pouvez créer et émettre un événement avec les éléments suivants sur votre élément

ng-click="$emit('customEvent')"

Ensuite, dans votre contrôleur, vous pouvez utiliser

$rootScope.$on('customEvent', function(){
    // do something
})

Démo

8
Jonathan de M.