$ apply vs $ digest no teste da diretiva

Se eu tiver uma diretiva que responda ao status de um determinado atributo no escopo, e eu quiser alterar esse atributo no meu teste e verificar se ele responde corretamente, qual é a melhor maneira de fazer essa alteração?

Eu vi ambos os padrões:

scope.$apply(function() { scope.myAttribute = true; }); 

e

 scope.myAttribute = true; scope.$digest(); 

Qual é a diferença entre eles, e qual é melhor e por quê?

scope.$digest() irá triggersr observadores no escopo atual, e em todos os seus filhos também. scope.$apply irá avaliar a function passada e executar $rootScope.$digest() .

O primeiro é mais rápido, pois precisa avaliar os observadores para o escopo atual e seus filhos. O segundo é mais lento, já que precisa avaliar os observadores para $rootScope e todos os seus escopos filho.

Quando ocorre um erro em um dos observadores e você usa o scope.$digest , ele não é manipulado pelo serviço $exceptionHandler , portanto você precisa lidar com a exceção. scope.$apply um bloco try-catch internamente e passa todas as exceções para $exceptionHandler .

Como a própria documentação menciona, o ciclo $ digest é feito a qualquer momento em que você faz $scope.$apply . De acordo com o guia do desenvolvedor sobre o escopo

Depois de avaliar a expressão, o método $ apply executa um $ digest. Na fase $ digest, o escopo examina todas as expressões $ watch e compara-as com o valor anterior.

E de acordo com a documentação da API do escopo

Normalmente você não chama $ digest () diretamente nos controladores ou nas diretivas. Em vez disso, uma chamada para $ apply () (normalmente de dentro de diretivas) forçará um $ digest ().

Portanto, você não deve chamar explicitamente $digest , e chamar o método $apply acionaria um ciclo de digitação.