6

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

4

1 回答 1

11

问题是它快速连续执行$digest两次$rootScope,并且在重叠时抛出错误。为了解决这个问题,您可以简单地将两个调用包装起来$location.path()in $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 循环结束

于 2014-08-05T21:59:34.630 回答