Error: $rootScope:inprog — What is the correct way to 'not' execute $apply in angular?

て烟熏妆下的殇ゞ 提交于 2019-12-24 10:57:41

问题


AngularJS Wiki - Anti-Patterns states the following:

Don't do if (!$scope.$$phase) $scope.$apply(), it means your $scope.$apply() isn't high enough in the call stack.

And I kind of understand this. There is a built in logic that determines when what needs to be executed. And when an external developer, without direct insigt in the runtime executions of different procedures, determines what should run where, it counteracts the framework.

But I am currently uploading a large file where the upload progress is displayed through a progress bar. The library I use (resumableJS) in turn has an event called fileProgress, that is called when the upload is progressing. If I do nothing during that event, the bar is not updating. If I put $scope.$apply() there, the bar is updated accordingly, but I get the digest and/or apply already in progress error. Finally, with the help of the $$phase check I get the best of both worlds, an updated progress bar without any errors.

So what is the correct alternative to get my bar updated while not interfering with the angulars processing order?


回答1:


In your case you are trying to run a digest cycle, when a digest cycle is already in phase. So it's throwing an error

You can use something like setTimeout(fn,0). What it basically does is it adds new message to the queue immediately, and will be processed when the currently executing code is finished.

So in your angular code, where you are explicitly doing your $scope.$apply(), change it to the code below and it should work.

$timeout(function(){
   $scope.$apply();
},0)



回答2:


Error: $rootScope:inprog Action Already In Progress

At any point in time there can be only one $digest or $apply operation in progress. This is to prevent very hard to detect bugs from entering your application. The stack trace of this error allows you to trace the origin of the currently executing $apply or $digest call, which caused the error.

Common Causes

Apart from simply incorrect calls to $apply or $digest there are some cases when you may get this error through no fault of your own.

Inconsistent API (Sync/Async)

This error is often seen when interacting with an API that is sometimes sync and sometimes async.

This is not an ideal design choice on the part of the 3rd party library.

To resolve this type of issue, either fix the api to be always synchronous or asynchronous or force your callback handler to always run asynchronously by using the $timeout service.

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

Here we have used $timeout to schedule the changes to the scope in a future call stack. By providing a timeout period of 0ms, this will occur as soon as possible and $timeout will ensure that the code will be called in a single $apply block.

** Only use this technique as a last resort **.

It is best to find the source of the error and fix it.

For more information, see AngularJS Error Reference - $rootScope/inprog - Diagnosing This Error

See also,

  • AngularJS Developer Guide (V1.1) Runtime Concepts

  • AngularJS $rootScope/Scope API Reference



来源:https://stackoverflow.com/questions/42923234/error-rootscopeinprog-what-is-the-correct-way-to-not-execute-apply-in-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!