所以我有一个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
});
如何使它适用于所有事件处理程序?
plnkr示例
问题是它在$rootScope
上连续快速执行两次$digest
,当出现重叠时会抛出错误。为了解决这个问题,您可以简单地将对$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示例,与原始文章中的代码略有不同。
参考:
等待$digest周期结束