Vejo http://docs.angularjs.org/error/$rootScope:inprog
O problema surge quando você $apply
recebe uma chamada que, às vezes, é executada de forma assíncrona fora do código Angular (quando $ apply deve ser usado) e, às vezes, de forma síncrona dentro do código Angular (que causa o erro$digest already in progress
erro).
Isso pode acontecer, por exemplo, quando você tem uma biblioteca que busca assincronamente itens de um servidor e os armazena em cache. Na primeira vez que um item é solicitado, ele é recuperado de forma assíncrona para não bloquear a execução do código. Na segunda vez, no entanto, o item já está no cache para que possa ser recuperado de forma síncrona.
A maneira de evitar esse erro é garantir que o código que chama $apply
seja executado de forma assíncrona. Isso pode ser feito executando o código dentro de uma chamada $timeout
com o atraso definido como 0
(que é o padrão). No entanto, chamar seu código para dentro $timeout
remove a necessidade de chamar $apply
, porque $ timeout acionará outro $digest
ciclo por si só, que, por sua vez, fará toda a atualização necessária etc.
Solução
Em resumo, em vez de fazer isso:
... your controller code...
$http.get('some/url', function(data){
$scope.$apply(function(){
$scope.mydate = data.mydata;
});
});
... more of your controller code...
faça isso:
... your controller code...
$http.get('some/url', function(data){
$timeout(function(){
$scope.mydate = data.mydata;
});
});
... more of your controller code...
Somente ligue $apply
quando você souber que o código em execução será sempre executado fora do código Angular (por exemplo, sua chamada para $ apply ocorrerá dentro de um retorno de chamada chamado por código fora do código Angular).
A menos que alguém esteja ciente de alguma desvantagem impactante do uso $timeout
excessivo $apply
, não vejo por que você nem sempre pode usar $timeout
(com atraso zero) em vez de $apply
, pois fará aproximadamente a mesma coisa.