Fehler: $apply bereits in Arbeit

Stapelverfolgung:

Error: $apply already in progress
at Error (<anonymous>)
at beginPhase (file:///android_asset/www/built.min.js:7:22740)
at Object.Scope.$apply (file:///android_asset/www/built.min.js:7:25967)
at navigator.geolocation.getCurrentPosition.that (file:///android_asset/www/built.min.js:13:8670)
at Object.geolocation.getCurrentPosition (file:///android_asset/www/plugins/org.apache.cordova.core.geolocation/www/geolocation.js:122:13)
at Object.getCurrentPosition (file:///android_asset/www/built.min.js:13:8589)
at Object.getCurrentPosition (file:///android_asset/www/built.min.js:13:8277)
at Object.getCurrentCity (file:///android_asset/www/built.min.js:13:8941)
at Object.$scope.locateDevice (file:///android_asset/www/built.min.js:13:10480)
at file:///android_asset/www/built.min.js:7:12292:7

verweist auf diesen Code http://pastebin.com/B9V6yvFu

    getCurrentPosition: cordovaReady(function (onSuccess, onError, options) {

        navigator.geolocation.getCurrentPosition(function () {
            var that = this,
                args = arguments;

            if (onSuccess) {
                $rootScope.$apply(function () {
                    onSuccess.apply(that, args);
                });
            }
        }, function () {
            var that = this,
                args = arguments;
            if (onError) {
                $rootScope.$apply(function () {
                    onError.apply(that, args);
                });
            }
        }, {
            enableHighAccuracy: true,
            timeout: 20000,
            maximumAge: 18000000
        });
    })

Seltsam, auf meinem LG4X funktioniert es einwandfrei, aber auf meinem samsung s2 gibt es den oben genannten Fehler aus. Irgendwelche Ideen, was falsch ist?

Lösung

Sie erhalten diesen Fehler, weil Sie "$apply" innerhalb eines bestehenden Verdauungszyklus aufrufen.

Die große Frage ist: Warum rufen Sie "$apply" auf? Sie sollten $apply niemals aufrufen müssen, es sei denn, Sie haben eine Schnittstelle zu einem Nicht-Angular-Ereignis. Das Vorhandensein von "$apply" bedeutet normalerweise, dass ich etwas falsch mache (es sei denn, das "$apply" kommt von einem nicht-angularen Ereignis).

Wenn $apply hier wirklich angebracht ist, sollte man einen "safe apply" Ansatz in Betracht ziehen:

https://coderwall.com/p/ngisma

Kommentare (4)

Sie können diese Anweisung verwenden:

if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
    $scope.$apply();
}
Kommentare (2)

Wenn der Geltungsbereich in einigen Fällen angewendet werden muss, können Sie eine Zeitüberschreitung festlegen, so dass die Anwendung von $apply bis zum nächsten Tick verschoben wird

setTimeout(function(){ scope.$apply(); });

oder verpacken Sie Ihren Code in ein $timeout(function(){ .. }); verpacken, denn dann wird der Bereich am Ende der Ausführung automatisch mit $apply versehen. Wenn sich Ihre Funktion synchron verhalten soll, würde ich Ersteres tun.

Kommentare (3)