Why does Angular ignore subsequent calls to $ digest?

Below should be the most common Angular.js error, developers need to fix the problems at some point.

Error: $ apply is already running

Sometimes a call was $scope.$applynot required in the end, and removing it fixes the problem. In some cases, this may be required, and therefore developers resort to the following template.

if(!$scope.$$phase) {
    $scope.$apply();
}

My question is why Angular just does not check $scope.$$phaseand returnwithout doing anything when the loop is called $digestor when it $scope.$applyis called and not complaining and throwing an error, it is so insidiously difficult to track .

Angular failed to check only $$phaseat the input points of any methods that run $digest, and save consumers from having to overcome problems?

Are there any consequences for eliminating non-local calls $scope.$apply, other than unwanted clock attacks that would prevent checking for $$phase?

Why doesn't it $$phasecheck the default value, and not weirdness?

Background

I am updating Angular from 1.2.1to 1.2.6and this exception is thrown when the page loads, so I have no idea where it came from. Hence the question, why do we even have to keep track of this obscure error, having no idea where to look for it in our code?

+4
1

- , $scope.$apply() . , : $apply , , , , , , , , .

(, , $scope.$$phase), , "$apply ". ( $scope ) , , , (. ).

$apply?

$apply - $scope , Angular. , , $scope (, , ), $apply . , , .

, Javascript , Angular . , , , , -, , .. $scope . Angular, . , " ". Google , :

function Controller($scope) {
    $scope.coordinates = [];
    //...
    var map = new google.maps.Map(mapElement, mapOptions);
    google.maps.event.addDomListener(map, 'dblclick', function (mouseEvent) {
        $scope.coordinates.push(mouseEvent.latLng);
    });
}

http://jsfiddle.net/mhelvens/XLPY9/1/

, $scope.coordinates $apply less 'call-stack. , Angular Google .

$apply?

Angular $scope.$apply():

function Controller($scope) {
    //...
    google.maps.event.addDomListener(map, 'dblclick', function (mouseEvent) {
        $scope.$apply(function () {
            $scope.coordinates.push(mouseEvent.latLng);
        });
    });
}

http://jsfiddle.net/mhelvens/XLPY9/2/

, . "$apply already in progress" , . Google, :

app.factory('onGoogleMapsEvent', function ($rootScope) {
    return function (element, event, callback) {
        google.maps.event.addDomListener(element, event, function (e) {
            $rootScope.$apply(function () { callback(e); });
        });
    };
});

function Controller($scope, onGoogleMapsEvent) {
    //...
    onGoogleMapsEvent(map, 'dblclick', function (mouseEvent) {
        $scope.coordinates.push(mouseEvent.latLng);
    });
}

http://jsfiddle.net/mhelvens/XLPY9/3/

onGoogleMapsEvent Angular -aware, " ", (, , ). $apply ; .

Angular . , $timeout.

<$apply already in progress

, , , , , , $apply :

onGoogleMapsEvent(map, 'dblclick', function (mouseEvent) {
    $scope.$apply(function () { // Error: $apply already in progress
        $scope.coordinates.push(mouseEvent.latLng);
    });
});

http://jsfiddle.net/mhelvens/XLPY9/4/

$apply (onGoogleMapsEvent , , "" ). , , :

Error: [$rootScope:inprog] $apply already in progress
    ...
    at Scope.$apply (.../angular.js:11675:11)
    at http://fiddle.jshell.net/mhelvens/XLPY9/4/show/:50:16
    ...
    at Scope.$apply (.../angular.js:11676:23)
    at dl.ondblclick (http://fiddle.jshell.net/mhelvens/XLPY9/4/show/:33:24)
    ...

: , Scope.$apply. , Scope.$apply ( Scope.$digest , ; $digest $apply).

, . , . Javascript. : ", " ", $apply". , .

, . , $apply. Angular , .

+8

All Articles