调用$rootScope时$digest已在进行中$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
});

如何使它适用于所有事件处理程序?

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周期结束

最新更新