在$ rootScope中调用$ digest。$ apply()快速连续

时间:2014-08-05 21:48:26

标签: angularjs events location rootscope angular-digest

所以我有一个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 example

1 个答案:

答案 0 :(得分:11)

问题在于它在$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示例,与原始帖子中的代码略有不同。

<强>参考:

wait for end of $digest cycle