safeapply new angularjs cordova angular-digest

angularjs - new - $ aplicar error en curso



broadcast angularjs (10)

Stack trace:

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

se refiere a este código 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 }); })

Extraño, en mi LG4X funciona bien, sin embargo, en mi samsung s2 arroja el error anterior. ¿Alguna idea de lo que está mal?


En 1.3 angular, creo, agregaron una nueva función - $scope.$applyAsync() . Esta función llama a aplicar más tarde; al menos unos 10 ms más tarde. No es perfecto, pero al menos elimina el molesto error.

https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope # $ applyAsync


En cualquier momento, solo puede haber una operación $digest o $apply en progreso. Esto es para evitar que errores muy difíciles de detectar ingresen a su aplicación. El seguimiento de la pila de este error le permite rastrear el origen de la ejecución actual de la llamada $apply o $digest , que provocó el error.

Más información: https://docs.angularjs.org/error/$rootScope/inprog?p0=$apply


En mi caso uso $apply con UI de calendario angular para vincular algún evento:

$scope.eventClick = function(event){ $scope.$apply( function() { $location.path(''/event/'' + event.id); }); };

Después de leer el documento del problema: https://docs.angularjs.org/error/ $ rootScope / inprog

La parte Inconsistent API (Sync / Async) es muy interesante:

Por ejemplo, imagina una biblioteca de terceros que tiene un método que recuperará datos para nosotros. Como puede estar haciendo una llamada asincrónica a un servidor, acepta una función de devolución de llamada, que se invocará cuando lleguen los datos.

Como el constructor MyController siempre se crea una instancia desde una llamada $ apply, nuestro controlador intenta ingresar un nuevo bloque $ apply desde uno.

Cambio el código a:

$scope.eventClick = function(event){ $timeout(function() { $location.path(''/event/'' + event.id); }, 0); };

Funciona de maravilla !

Aquí hemos usado $ timeout para programar los cambios en el alcance en una pila de llamadas futura. Al proporcionar un período de tiempo de espera de 0ms, esto ocurrirá tan pronto como sea posible y $ timeout garantizará que el código se invoque en un único bloque $ apply.


Está recibiendo este error porque llama $apply dentro de un ciclo de digestión existente.

La gran pregunta es: ¿por qué llamas $apply ? No deberías necesitar llamar $apply menos que estés interactuando desde un evento no angular. La existencia de $apply generalmente significa que estoy haciendo algo mal (a menos que, una vez más, la $ apply ocurra a partir de un evento no Angular).

Si $apply realmente es apropiado aquí, considere usar un enfoque de "aplicación segura":

https://coderwall.com/p/ngisma


Llamo a $ scope. $ Aplicar de esta manera para ignorar llamada múltiple de una vez.

var callApplyTimeout = null; function callApply(callback) { if (!callback) callback = function () { }; if (callApplyTimeout) $timeout.cancel(callApplyTimeout); callApplyTimeout = $timeout(function () { callback(); $scope.$apply(); var d = new Date(); var m = d.getMilliseconds(); console.log(''$scope.$apply(); call '' + d.toString() + '' '' + m); }, 300); }

simplemente llame

callApply();


Puedes usar esta declaración:

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


Sé que es una pregunta antigua, pero si realmente necesitas usar $ scope. $ ApplyAsync ();


Si se debe aplicar el alcance en algunos casos, puede establecer un tiempo de espera para que la $ apply se posponga hasta el próximo tick

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

o envuelva su código en $ timeout (function () {..}); porque automáticamente $ aplicará el alcance al final de la ejecución. Si necesita que su función se comporte sincrónicamente, yo haría la primera.



Solo resolvió este problema. Está documentado aquí .

$rootScope.$apply dos veces en el mismo flujo. Todo lo que hice fue envolver el contenido de la función de servicio con un setTimeout(func, 1) .