Ver http://docs.angularjs.org/error/$rootScope:inprog
El problema surge cuando tiene una llamada $apply
que a veces se ejecuta de forma asincrónica fuera del código angular (cuando se debe usar $ apply) y, a veces, sincrónicamente dentro del código angular (que causa el $digest already in progress
error).
Esto puede suceder, por ejemplo, cuando tiene una biblioteca que recupera asincrónicamente elementos de un servidor y los almacena en caché. La primera vez que se solicita un elemento, se recuperará de forma asincrónica para no bloquear la ejecución del código. La segunda vez, sin embargo, el elemento ya está en la memoria caché, por lo que puede recuperarse sincrónicamente.
La forma de evitar este error es asegurarse de que el código que llama $apply
se ejecute de forma asincrónica. Esto se puede hacer ejecutando su código dentro de una llamada a $timeout
con el retraso establecido en 0
(que es el valor predeterminado). Sin embargo, llamar a su código adentro $timeout
elimina la necesidad de llamar $apply
, porque $ timeout activará otro$digest
ciclo por sí solo, lo que, a su vez, hará todas las actualizaciones necesarias, etc.
Solución
En resumen, en lugar de hacer esto:
... your controller code...
$http.get('some/url', function(data){
$scope.$apply(function(){
$scope.mydate = data.mydata;
});
});
... more of your controller code...
hacer esto:
... your controller code...
$http.get('some/url', function(data){
$timeout(function(){
$scope.mydate = data.mydata;
});
});
... more of your controller code...
Solo llamar $apply
cuando sepa que el código en ejecución siempre se ejecutará fuera del código angular (por ejemplo, su llamada a $ apply se realizará dentro de una devolución de llamada que se llama por código fuera de su código angular).
A menos que alguien sea consciente de alguna desventaja impactante al usarlo en $timeout
exceso $apply
, no veo por qué no siempre puede usarlo $timeout
(con cero retraso) en lugar de hacerlo $apply
, ya que hará aproximadamente lo mismo.