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

前端 未结 28 2765
伪装坚强ぢ
伪装坚强ぢ 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:01

    From a recent discussion with the Angular guys on this very topic: For future-proofing reasons, you should not use $$phase

    When pressed for the "right" way to do it, the answer is currently

    $timeout(function() {
      // anything you want can go here and will safely be run on the next digest.
    })
    

    I recently ran into this when writing angular services to wrap the facebook, google, and twitter APIs which, to varying degrees, have callbacks handed in.

    Here's an example from within a service. (For the sake of brevity, the rest of the service -- that set up variables, injected $timeout etc. -- has been left off.)

    window.gapi.client.load('oauth2', 'v2', function() {
        var request = window.gapi.client.oauth2.userinfo.get();
        request.execute(function(response) {
            // This happens outside of angular land, so wrap it in a timeout 
            // with an implied apply and blammo, we're in action.
            $timeout(function() {
                if(typeof(response['error']) !== 'undefined'){
                    // If the google api sent us an error, reject the promise.
                    deferred.reject(response);
                }else{
                    // Resolve the promise with the whole response if ok.
                    deferred.resolve(response);
                }
            });
        });
    });
    

    Note that the delay argument for $timeout is optional and will default to 0 if left unset ($timeout calls $browser.defer which defaults to 0 if delay isn't set)

    A little non-intuitive, but that's the answer from the guys writing Angular, so it's good enough for me!

提交回复
热议问题