$ emit или $ трансляции событий от обслуживания и слушайте их в контроллере (или несколько)

StackOverflow https://stackoverflow.com//questions/23013883

Вопрос

Я закодировал простой пример, где я хочу излучать / транслировать событие с сервиса, и я хочу, чтобы это событие было прослушиваться контроллером и изменить интернет-интерфейс, но я не могу заставить его работать и отладки кодакажется, останавливается в слушателе, но он не выполняет функцию.

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

Сервис:

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

Контроллер

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';
      });
    }]);
.

Индекс

<!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>
.

Решение:

Как сообщили бренда Ivarni или Walter, призыв к функции службы, которые запускают событие, должно быть размещено после прослушивателя, если вы не запускаете событие, у которого нет слушателя, не способного прослушивания.

Нам нужно просто изменить контроллер следующим образом:

Сервис

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();
        }]);
.

Это было полезно?

Решение

Вы запускаете событие, прежде чем прикрепить слушатель.

Попробуйте:

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

Другие советы

Просто поместите VerviceteSt.test () ниже своего слушателя в своем контроллере, как это:

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

Вы прикрепите слушателя сразу после вызова теста (), и там просто пропускает событие.

Решение, которое я обнаружил, что лучше всего работать в приложении среднего размера, состоит в том, чтобы создать обертку вокруг функции $ Emit и задержать $ emit с несколькими миллисекунами, достаточно, достаточно, для всех событий, которые будут зарегистрированы.

Вы также можете представить еще несколько вкусностей в обертку, например, передача его текущей $ или позвольте ему создать новый детский объем $ rootscope (который будет только один уровень внизу, поэтому все равно будет быстро при распространенииДо $ rootscope) и используйте это в качестве канала данных, разрушение событий после объема умирает и т. Д. ...

Вот весь исходный код: http://jsfiddle.net/gabrielcatalin/2urr7

А вот выдержка:

/**
 * 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);
}
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top