Da documenti:
detectChanges (): void
Verifica il rilevatore di modifiche e i relativi figli.
Significa che se c'è un caso in cui qualcosa all'interno del tuo modello (la tua classe) è cambiato ma non ha rispecchiato la vista, potresti aver bisogno di avvisare Angular per rilevare quelle modifiche (rilevare le modifiche locali) e aggiornare la vista.
I possibili scenari potrebbero essere:
1- Il rilevatore di modifiche è staccato dalla vista (vedi staccare )
2- Si è verificato un aggiornamento ma non è stato all'interno della zona angolare, pertanto Angular non lo conosce.
Come quando una funzione di terze parti ha aggiornato il tuo modello e successivamente desideri aggiornare la vista.
someFunctionThatIsRunByAThirdPartyCode(){
yourModel.text = "new text";
}
Poiché questo codice è al di fuori della zona di Angular (probabilmente), molto probabilmente è necessario assicurarsi di rilevare le modifiche e aggiornare la vista, quindi:
myFunction(){
someFunctionThatIsRunByAThirdPartyCode();
// Let's detect the changes that above function made to the model which Angular is not aware of.
this.cd.detectChanges();
}
NOTA :
Esistono altri modi per far funzionare sopra, in altre parole, ci sono altri modi per portare quel cambiamento all'interno del ciclo del cambiamento angolare.
** È possibile racchiudere quella funzione di terze parti all'interno di una zona.run:
myFunction(){
this.zone.run(this.someFunctionThatIsRunByAThirdPartyCode);
}
** È possibile racchiudere la funzione all'interno di un setTimeout:
myFunction(){
setTimeout(this.someFunctionThatIsRunByAThirdPartyCode,0);
}
3- Ci sono anche casi in cui si aggiorna il modello al change detection cycle
termine del processo, in cui in questi casi viene visualizzato questo temuto errore:
"L'espressione è cambiata dopo che è stata controllata";
Ciò significa generalmente (dal linguaggio Angular2):
Ho visto un cambiamento nel tuo modello che è stato causato da uno dei miei modi accettati (eventi, richieste XHR, setTimeout e ...) e poi ho eseguito il rilevamento delle modifiche per aggiornare la tua vista e l'ho finito, ma poi c'è stato un altro nel tuo codice che ha aggiornato di nuovo il modello e non voglio eseguire nuovamente il rilevamento delle modifiche perché non esiste più un controllo sporco come AngularJS: D e dovremmo usare un flusso di dati a senso unico!
Incontrerai sicuramente questo errore: P.
Un paio di modi per risolverlo:
1- Modo corretto : assicurarsi che l'aggiornamento sia all'interno del ciclo di rilevamento delle modifiche (gli aggiornamenti di Angular2 sono un flusso unidirezionale che si verifica una volta, non aggiornare il modello successivamente e spostare il codice in un luogo / orario migliore).
2- Modo pigro : esegui detectChanges () dopo quell'aggiornamento per rendere felice angular2, questo non è sicuramente il modo migliore, ma come hai chiesto quali sono i possibili scenari, questo è uno di questi.
In questo modo stai dicendo: So sinceramente che hai eseguito il rilevamento delle modifiche, ma voglio che tu lo faccia di nuovo perché ho dovuto aggiornare qualcosa al volo dopo aver terminato il controllo.
3- Inserisci il codice in a setTimeout
, perché setTimeout
è patchato per zona e verrà eseguito detectChanges
al termine.
Dai documenti
markForCheck() : void
Contrassegna tutti gli antenati ChangeDetectionStrategy come da verificare.
Ciò è necessario soprattutto quando ChangeDetectionStrategy del componente è OnPush .
OnPush stesso significa, eseguire il rilevamento delle modifiche solo se si è verificato uno di questi:
1- Uno degli @input del componente è stato completamente sostituito con un nuovo valore o, semplicemente, se il riferimento della proprietà @Input è cambiato del tutto.
Quindi se ChangeDetectionStrategy del tuo componente è OnPush e hai:
var obj = {
name:'Milad'
};
E poi lo aggiorni / muti come:
obj.name = "a new name";
Questo non aggiornerà il riferimento obj , quindi il rilevamento delle modifiche non verrà eseguito, quindi la vista non riflette l'aggiornamento / mutazione.
In questo caso devi dire manualmente ad Angular di controllare e aggiornare la vista (markForCheck);
Quindi se hai fatto questo:
obj.name = "a new name";
Devi fare questo:
this.cd.markForCheck();
Piuttosto, di seguito causerebbe l'esecuzione di un rilevamento delle modifiche:
obj = {
name:"a new name"
};
Che ha completamente sostituito il precedente obj con un nuovo {}
;
2- Un evento è stato generato, come un clic o qualcosa del genere o uno qualsiasi dei componenti figlio ha emesso un evento.
Eventi come:
- Clic
- keyup
- Eventi in abbonamento
- eccetera.
Quindi in breve:
Utilizzalo detectChanges()
quando hai aggiornato il modello dopo che Angular ha eseguito il rilevamento delle modifiche o se l'aggiornamento non è stato affatto nel mondo angolare.
Utilizzare markForCheck()
se si utilizza OnPush e si sta aggirando il ChangeDetectionStrategy
mutando alcuni dati o se si è aggiornato il modello all'interno di un setTimeout ;