1

AngularJS Wiki - Anti-Patterns声明如下:

不要这样做if (!$scope.$$phase) $scope.$apply(),这意味着你$scope.$apply()在调用堆栈中不够高。

我有点理解这一点。有一个内置逻辑可以确定何时需要执行什么。而且,当外部开发人员在没有直接参与不同过程的运行时执行的情况下确定应该在哪里运行时,它会抵消框架。

但我目前正在上传一个大文件,其中通过进度条显示上传进度。我使用的库 (resumableJS) 又具有一个名为 fileProgress 的事件,在上传过程中调用该事件。如果我在那次活动期间什么都不做,则该栏不会更新。如果我放在$scope.$apply()那里,栏会相应地更新,但我会得到摘要和/或应用已经在进行中的错误。最后,在$$phase检查的帮助下,我得到了两全其美,更新的进度条没有任何错误。

那么在不干扰角度处理顺序的情况下更新我的条的正确替代方法是什么?

4

2 回答 2

3

在您的情况下,您正在尝试运行摘要周期,而摘要周期已经处于阶段。所以它抛出一个错误

你可以使用 setTimeout(fn,0) 之类的东西。它的基本作用是立即将新消息添加到队列中,并在当前执行的代码完成时进行处理。

因此,在您明确执行 $scope.$apply() 的角度代码中,将其更改为下面的代码,它应该可以工作。

$timeout(function(){
   $scope.$apply();
},0)
于 2017-03-21T09:46:59.673 回答
1

错误:$rootScope:inprog操作已在进行中

在任何时间点都只能有一个$digest$apply正在进行的操作。这是为了防止很难检测到的错误进入您的应用程序。此错误的堆栈跟踪允许您跟踪导致错误的当前执行$apply$digest调用的来源。

常见原因

除了简单的错误调用之外,$apply或者$digest在某些情况下,您可能会因为自己的过错而收到此错误。

不一致的 API(同步/异步)

与有时同步有时异步的 API 交互时,经常会出现此错误。

对于 3rd 方库而言,这不是一个理想的设计选择。

要解决此类问题,请将 api 修复为始终同步或异步,或者使用$timeout服务强制您的回调处理程序始终异步运行。

function MyController($scope, $timeout, thirdPartyComponent) {
  thirdPartyComponent.getData(function(someData) {
    $timeout(function() {
      $scope.someData = someData;
    }, 0);
  });
}

在这里,我们习惯于$timeout在未来的调用堆栈中安排对范围的更改。通过提供 0ms 的超时时间,这将尽快发生,并$timeout确保代码将在单个$apply块中被调用。

** 仅将此技术用作最后的手段**。

最好找到错误的根源并修复它。

有关更多信息,请参阅AngularJS 错误参考 - $rootScope/inprog - 诊断此错误

也可以看看,

于 2017-03-21T11:02:11.947 回答