AngularJS : Prevent error $digest already in progress when calling $scope.$apply()

前端 未结 28 2766
伪装坚强ぢ
伪装坚强ぢ 2020-11-21 22:31

I\'m finding that I need to update my page to my scope manually more and more since building an application in angular.

The only way I know of to do this is to call

相关标签:
28条回答
  • 2020-11-21 23:07

    Sometimes you will still get errors if you use this way (https://stackoverflow.com/a/12859093/801426).

    Try this:

    if(! $rootScope.$root.$$phase) {
    ...
    
    0 讨论(0)
  • 2020-11-21 23:09

    try using

    $scope.applyAsync(function() {
        // your code
    });
    

    instead of

    if(!$scope.$$phase) {
      //$digest or $apply
    }
    

    $applyAsync Schedule the invocation of $apply to occur at a later time. This can be used to queue up multiple expressions which need to be evaluated in the same digest.

    NOTE: Within the $digest, $applyAsync() will only flush if the current scope is the $rootScope. This means that if you call $digest on a child scope, it will not implicitly flush the $applyAsync() queue.

    Exmaple:

      $scope.$applyAsync(function () {
                    if (!authService.authenticated) {
                        return;
                    }
    
                    if (vm.file !== null) {
                        loadService.setState(SignWizardStates.SIGN);
                    } else {
                        loadService.setState(SignWizardStates.UPLOAD_FILE);
                    }
                });
    

    References:

    1.Scope.$applyAsync() vs. Scope.$evalAsync() in AngularJS 1.3

    1. AngularJs Docs
    0 讨论(0)
  • 2020-11-21 23:10

    When you get this error, it basically means that it's already in the process of updating your view. You really shouldn't need to call $apply() within your controller. If your view isn't updating as you would expect, and then you get this error after calling $apply(), it most likely means you're not updating the the model correctly. If you post some specifics, we could figure out the core problem.

    0 讨论(0)
  • You should use $evalAsync or $timeout according to the context.

    This is a link with a good explanation:

    http://www.bennadel.com/blog/2605-scope-evalasync-vs-timeout-in-angularjs.htm

    0 讨论(0)
  • 2020-11-21 23:10

    similar to answers above but this has worked faithfully for me... in a service add:

        //sometimes you need to refresh scope, use this to prevent conflict
        this.applyAsNeeded = function (scope) {
            if (!scope.$$phase) {
                scope.$apply();
            }
        };
    
    0 讨论(0)
  • 2020-11-21 23:13

    I have been using this method and it seems to work perfectly fine. This just waits for the time the cycle has finished and then triggers apply(). Simply call the function apply(<your scope>) from anywhere you want.

    function apply(scope) {
      if (!scope.$$phase && !scope.$root.$$phase) {
        scope.$apply();
        console.log("Scope Apply Done !!");
      } 
      else {
        console.log("Scheduling Apply after 200ms digest cycle already in progress");
        setTimeout(function() {
            apply(scope)
        }, 200);
      }
    }
    
    0 讨论(0)
提交回复
热议问题