Vedi http://docs.angularjs.org/error/$rootScope:inprog
Il problema sorge quando si riceve una chiamata $apply
che a volte viene eseguita in modo asincrono al di fuori del codice angolare (quando si deve usare $ apply) e talvolta in modo sincrono all'interno del codice angolare (che causa il$digest already in progress
errore).
Ciò può accadere, ad esempio, quando si dispone di una libreria che recupera in modo asincrono elementi da un server e li memorizza nella cache. La prima volta che un elemento viene richiesto, verrà recuperato in modo asincrono in modo da non bloccare l'esecuzione del codice. La seconda volta, tuttavia, l'elemento è già nella cache, quindi può essere recuperato in modo sincrono.
Il modo per prevenire questo errore è garantire che il codice che chiama $apply
sia eseguito in modo asincrono. Questo può essere fatto eseguendo il codice all'interno di una chiamata $timeout
con il ritardo impostato su 0
(che è l'impostazione predefinita). Tuttavia, chiamare il codice all'interno $timeout
rimuove la necessità di chiamare $apply
, perché $ timeout ne attiverà un altro$digest
ciclo da solo, che a sua volta eseguirà tutti gli aggiornamenti necessari, ecc.
Soluzione
In breve, invece di farlo:
... your controller code...
$http.get('some/url', function(data){
$scope.$apply(function(){
$scope.mydate = data.mydata;
});
});
... more of your controller code...
Fai questo:
... your controller code...
$http.get('some/url', function(data){
$timeout(function(){
$scope.mydate = data.mydata;
});
});
... more of your controller code...
Chiama solo $apply
quando sai che il codice in esecuzione verrà sempre eseguito al di fuori del codice angolare (ad es. La tua chiamata a $ apply avverrà all'interno di un callback chiamato da un codice esterno al tuo codice angolare).
A meno che qualcuno non sia a conoscenza di uno svantaggio di impatto sull'uso di $timeout
over $apply
, non vedo perché non si possa sempre usare $timeout
(con zero delay) invece di $apply
, poiché farà circa la stessa cosa.