$digest уже выполняется при вызове $rootScope.$apply() в быстрой последовательности
Поэтому у меня есть служба AngularJS, которая прослушивает некоторые события. При обработке этих событий мне нужно вызывать разные контроллеры и в конечном итоге загружать новое представление. В одном обработчике событий я использую $location.path(), затем вызываю $rootScope.apply() для запуска маршрутизации к контроллеру. Это прекрасно работает для этого события, но в других я получаю следующую ошибку: $rootScope:inprog Action Already In Progress
, Я предполагаю, что это работает в первом сценарии, потому что $rootScope.apply() вызывается из другой функции обратного вызова внутри функции слушателя, где другие обработчики пытаются вызвать его только из функции слушателя события.
//angular service
$rootScope.$on('MY_EVENT', function (event, msg) {
MyClass.doSomething(msg, function (response) {
$location.path("/view1");
$rootScope.$apply(); //WORKS FINE
});
});
$rootScope.$on('MY_OTHER_EVENT', function (event, msg) {
$location.path("/view2");
$rootScope.$apply(); //ERROR
});
Как я могу заставить его работать для всех обработчиков событий?
1 ответ
Проблема в том, что он выполняет $digest
на $rootScope
дважды в быстрой последовательности и выдает ошибку, когда есть совпадение. Чтобы обойти это, вы можете просто обернуть оба вызова $location.path()
в $timeout
, как вы сделали в первый раз в вашем примере plnkr. Это заставит его ждать $digest
цикл для завершения.
Вы также можете удалить явные вызовы $rootScope.$apply()
,
$rootScope.$on('FIRST_EVENT', function(event, msg) {
$timeout(function() {
$location.path("/view1");
});
});
$rootScope.$on('SECOND_EVENT', function(event, msg) {
$timeout(function() {
$location.path("/view2");
});
});
Замечания:
Этот код основан на примере plnkr, который немного отличается от кода в оригинальном посте.
Ссылка: