Question

J'ai codé un exemple simple où je veux émettre / diffuser un événement d'un service et je souhaite que cet événement soit écouté par un contrôleur et changez l'interface utilisateur, mais je ne peux pas faire fonctionner et déboguer le codesemble s'arrêter dans l'auditeur mais cela n'exécute pas la fonction.

http://plnkr.co/edit/eglCq7zellfkp86yDyzoe?p=preview

service:

angular.module('ServiceModule', []).
service('servicetest', ['$rootScope', function($rootScope){
    this.test = function(){
      $rootScope.$emit('testevent');
    };
}]);

contrôleur

angular.module('ControllerModule', ['ServiceModule']).
    controller('ControllerTest', ['$scope','$rootScope','servicetest', function($scope, $rootScope, servicetest){
      $scope.name = 'World';
      servicetest.test();
      $rootScope.$on('testevent', function(){
        $scope.name = 'Joe';
      });
    }]);

index

<!DOCTYPE html>
<html ng-app="ControllerModule">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.2.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js" data-semver="1.2.16"></script>
    <script src="controller.js"></script>
    <script src="service.js"></script>
  </head>

  <body ng-controller="ControllerTest">
    <p>Hello {{name}}!</p>
  </body>

</html>

Solution:

Comme Ivarni ou Walter Marque rapporté, l'appel à la fonction de service qui déclenche l'événement doit être placé après l'auditeur, sinon vous déclenchez un événement qui n'a pas d'auditeur capable d'écouter.

Nous avons besoin de changer le contrôleur comme suit:

service

angular.module('ControllerModule', ['ServiceModule']).
        controller('ControllerTest', ['$scope','$rootScope','servicetest', function($scope, $rootScope, servicetest){
          $scope.name = 'World';
          $rootScope.$on('testevent', function(){
            $scope.name = 'Joe';
          });
          servicetest.test();
        }]);

Était-ce utile?

La solution

Vous déclenchez l'événement avant de joindre l'auditeur.

Essayez ceci:

  $rootScope.$on('testevent', function(){
    $scope.name = 'Joe';
  });
  servicetest.test();

Autres conseils

Il suffit de placer le serviceTest.test () sous votre auditeur de votre contrôleur, comme celui-ci:

  $rootScope.$on('testevent', function(){
    $scope.name = 'Joe';
  });
  servicetest.test();

Vous attachez l'auditeur juste après avoir appelé test (), et là-bas, et il suffit de manquer l'événement.

La solution que j'ai trouvée au mieux dans une application de taille moyenne consiste à créer une enveloppe autour de la fonction $ EMIT et à retarder l'émetteur $ avec quelques millisecondes, juste assez pour que tous les événements soient enregistrés.

Vous pouvez également introduire quelques plus de friandises dans l'emballage, comme le transmettre votre portée actuelle de $, ou la laisser créer une nouvelle portée de l'enfant de la rootscope $ (qui sera juste un niveau en dessous de sorte qu'il restera toujours rapide lors de la propagationjusqu'à $ rootscope), et utilisez-le comme le canal de données, la destruction des événements après la mort de la portée, etc.

Voici tout le code source: http://jsfiddle.net/gabrielcatalin/2urr7

Et voici un extrait:

/**
 * Waits a given amount of time before calling emitting
 * This works well when the event registration happens before emitting.
 *
 * @param name
 * @param fn
 * @param wait
 */
this.delayEmit = function (name, fn, wait) {
    // Because of the $scope's lifecycle the $emit(publish) happens after the $on(subscription)
    //  therefore that needs to be taken care of with a delay
    $timeout(function () {
        self.emit(name, fn);
    }, wait || 100);
}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top