Dos documentos:
detectChanges (): void
Verifica o detector de alterações e seus filhos.
Isso significa que, se houver um caso em que alguma coisa dentro do seu modelo (sua classe) tenha mudado, mas não tenha refletido a exibição, talvez seja necessário notificar o Angular para detectar essas alterações (detectar alterações locais) e atualizar a exibição.
Os cenários possíveis podem ser:
1- O detector de alterações é desconectado da visualização (consulte desanexação )
2- Uma atualização aconteceu, mas não está dentro da Zona Angular; portanto, a Angular não sabe disso.
Como quando uma função de terceiros atualiza seu modelo e você deseja atualizar a visualização depois disso.
someFunctionThatIsRunByAThirdPartyCode(){
yourModel.text = "new text";
}
Como esse código está fora da zona do Angular (provavelmente), você provavelmente precisará verificar as alterações e atualizar a exibição, assim:
myFunction(){
someFunctionThatIsRunByAThirdPartyCode();
// Let's detect the changes that above function made to the model which Angular is not aware of.
this.cd.detectChanges();
}
NOTA :
Existem outras maneiras de fazer o trabalho acima, em outras palavras, existem outras maneiras de trazer essa mudança para dentro do ciclo de mudança angular.
** Você pode agrupar essa função de terceiros dentro de um zone.run:
myFunction(){
this.zone.run(this.someFunctionThatIsRunByAThirdPartyCode);
}
** Você pode agrupar a função dentro de um setTimeout:
myFunction(){
setTimeout(this.someFunctionThatIsRunByAThirdPartyCode,0);
}
3- Existem também casos em que você atualiza o modelo após o change detection cycle
término, e nesses casos você recebe esse erro temido:
"A expressão mudou depois de ter sido verificada";
Isso geralmente significa (da linguagem Angular2):
Vi uma mudança no seu modelo causada por uma das minhas maneiras aceitas (eventos, solicitações XHR, setTimeout e ...) e, em seguida, executei minha detecção de alterações para atualizar sua visualização e a terminei, mas havia outra. no código que atualizou o modelo novamente e não quero executar minha detecção de alterações novamente porque não há mais verificação suja como o AngularJS: D e devemos usar o fluxo de dados de uma maneira!
Você definitivamente encontrará esse erro: P.
Duas maneiras de corrigi-lo:
1- Maneira adequada : verifique se a atualização está dentro do ciclo de detecção de alterações (as atualizações do Angular2 são um fluxo de sentido único que ocorre uma vez, não atualize o modelo depois disso e mova seu código para um local / hora melhor).
2- Maneira preguiçosa : execute detectChanges () após essa atualização para tornar angular2 feliz, essa definitivamente não é a melhor maneira, mas como você perguntou quais são os cenários possíveis, esse é um deles.
Dessa forma, você está dizendo: Sinceramente, sei que você executou a detecção de alterações, mas quero que você faça isso novamente porque tive que atualizar algo rapidamente depois que você terminou a verificação.
3- Coloque o código dentro de a setTimeout
, porque setTimeout
é corrigido pela zona e será executado detectChanges
depois que terminar.
Dos documentos
markForCheck() : void
Marca todos os ancestrais ChangeDetectionStrategy como a serem verificados.
Isso é necessário principalmente quando o ChangeDetectionStrategy do seu componente é OnPush .
OnPush propriamente dito significa, somente execute a detecção de alterações se alguma dessas coisas aconteceu:
1 - Um dos @inputs do componente foi completamente substituído por um novo valor, ou simplesmente, se a referência da propriedade @Input mudou completamente.
Portanto, se ChangeDetectionStrategy do seu componente for OnPush , você terá:
var obj = {
name:'Milad'
};
E então você atualiza / modifica como:
obj.name = "a new name";
Isso não atualizará a referência obj , portanto, a detecção de alterações não será executada, portanto a exibição não está refletindo a atualização / mutação.
Nesse caso, você precisa informar manualmente o Angular para verificar e atualizar a exibição (markForCheck);
Então, se você fez isso:
obj.name = "a new name";
Você precisa fazer isso:
this.cd.markForCheck();
Em vez disso, abaixo faria com que uma detecção de alterações fosse executada:
obj = {
name:"a new name"
};
O que substituiu completamente o objeto anterior por um novo {}
;
2- Um evento foi acionado, como um clique ou algo assim ou qualquer componente filho emitiu um evento.
Eventos como:
- Clique
- Keyup
- Eventos de assinatura
- etc.
Então, resumindo:
Use detectChanges()
quando você atualizou o modelo após a execução do angular, é a detecção de alterações ou se a atualização não está no mundo angular.
Use markForCheck()
se você estiver usando o OnPush e estiver ignorando ChangeDetectionStrategy
alguns dados ou tiver atualizado o modelo dentro de um setTimeout ;