$ emit или $ трансляции событий от обслуживания и слушайте их в контроллере (или несколько)
-
21-12-2019 - |
Вопрос
Я закодировал простой пример, где я хочу излучать / транслировать событие с сервиса, и я хочу, чтобы это событие было прослушиваться контроллером и изменить интернет-интерфейс, но я не могу заставить его работать и отладки кодакажется, останавливается в слушателе, но он не выполняет функцию.
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);
}
.