Aus Dokumenten:
detectChanges (): void
Überprüft den Änderungsdetektor und seine Kinder.
Wenn sich in Ihrem Modell (Ihrer Klasse) etwas geändert hat, das jedoch die Ansicht nicht widerspiegelt, müssen Sie Angular möglicherweise benachrichtigen, um diese Änderungen zu erkennen (lokale Änderungen zu erkennen) und die Ansicht zu aktualisieren.
Mögliche Szenarien könnten sein:
1- Der Änderungsdetektor ist von der Ansicht getrennt (siehe Abnehmen ).
2- Es wurde ein Update durchgeführt, das sich jedoch nicht in der Angular Zone befand. Daher weiß Angular nichts davon.
Zum Beispiel, wenn eine Drittanbieterfunktion Ihr Modell aktualisiert hat und Sie die Ansicht danach aktualisieren möchten.
someFunctionThatIsRunByAThirdPartyCode(){
yourModel.text = "new text";
}
Da sich dieser Code (wahrscheinlich) außerhalb der Angular-Zone befindet, müssen Sie höchstwahrscheinlich sicherstellen, dass die Änderungen erkannt und die Ansicht aktualisiert werden.
myFunction(){
someFunctionThatIsRunByAThirdPartyCode();
// Let's detect the changes that above function made to the model which Angular is not aware of.
this.cd.detectChanges();
}
HINWEIS :
Es gibt andere Möglichkeiten, die oben genannte Arbeit zu machen, mit anderen Worten, es gibt andere Möglichkeiten, diese Änderung in den Winkeländerungszyklus zu bringen.
** Sie können diese Drittanbieterfunktion in eine zone.run einbinden:
myFunction(){
this.zone.run(this.someFunctionThatIsRunByAThirdPartyCode);
}
** Sie können die Funktion in ein setTimeout einschließen:
myFunction(){
setTimeout(this.someFunctionThatIsRunByAThirdPartyCode,0);
}
3- Es gibt auch Fälle, in denen Sie das Modell aktualisieren, nachdem das abgeschlossen change detection cycle
ist. In diesen Fällen erhalten Sie diesen gefürchteten Fehler:
"Ausdruck hat sich geändert, nachdem er überprüft wurde";
Dies bedeutet im Allgemeinen (aus der Sprache Angular2):
Ich habe eine Änderung in Ihrem Modell gesehen, die durch eine meiner akzeptierten Methoden (Ereignisse, XHR-Anforderungen, setTimeout und ...) verursacht wurde, und dann habe ich meine Änderungserkennung ausgeführt, um Ihre Ansicht zu aktualisieren, und ich habe sie beendet, aber dann gab es eine andere Funktion in Ihrem Code, der das Modell erneut aktualisiert hat, und ich möchte meine Änderungserkennung nicht erneut ausführen, da es keine schmutzigen Überprüfungen wie AngularJS mehr gibt: D und wir sollten einen Einweg-Datenfluss verwenden!
Sie werden auf jeden Fall auf diesen Fehler stoßen: P.
Einige Möglichkeiten, dies zu beheben:
1- Richtige Methode : Stellen Sie sicher, dass sich die Aktualisierung innerhalb des Änderungserkennungszyklus befindet (Angular2-Aktualisierungen sind ein einmaliger Ablauf, aktualisieren Sie das Modell danach nicht mehr und verschieben Sie Ihren Code an einen besseren Ort / zu einer besseren Zeit).
2- Fauler Weg : Führen Sie nach diesem Update detectChanges () aus, um angle2 glücklich zu machen. Dies ist definitiv nicht der beste Weg, aber da Sie gefragt haben, welche Szenarien möglich sind, ist dies einer von ihnen.
Auf diese Weise sagen Sie: Ich weiß aufrichtig, dass Sie die Änderungserkennung ausgeführt haben, aber ich möchte, dass Sie dies erneut tun, da ich nach Abschluss der Überprüfung im laufenden Betrieb etwas aktualisieren musste.
3- Fügen Sie den Code in a ein setTimeout
, da er setTimeout
nach Zonen gepatcht ist und detectChanges
nach Abschluss ausgeführt wird.
Aus den Dokumenten
markForCheck() : void
Markiert alle Vorfahren von ChangeDetectionStrategy als zu prüfend.
Dies wird hauptsächlich benötigt, wenn die ChangeDetectionStrategy Ihrer Komponente OnPush ist .
OnPush selbst bedeutet, dass die Änderungserkennung nur ausgeführt wird, wenn eines der folgenden Ereignisse eingetreten ist:
1- Einer der @ -Eingänge der Komponente wurde vollständig durch einen neuen Wert ersetzt oder einfach ausgedrückt, wenn sich die Referenz der @ Input-Eigenschaft insgesamt geändert hat.
Wenn ChangeDetectionStrategy Ihrer Komponente OnPush ist und Sie haben:
var obj = {
name:'Milad'
};
Und dann aktualisieren / mutieren Sie es wie folgt:
obj.name = "a new name";
Dadurch wird die obj- Referenz nicht aktualisiert , daher wird die Änderungserkennung nicht ausgeführt, daher spiegelt die Ansicht nicht die Aktualisierung / Mutation wider .
In diesem Fall müssen Sie Angular manuell anweisen, die Ansicht zu überprüfen und zu aktualisieren (markForCheck).
Wenn Sie dies getan haben:
obj.name = "a new name";
Sie müssen dies tun:
this.cd.markForCheck();
Im Folgenden wird vielmehr eine Änderungserkennung ausgeführt:
obj = {
name:"a new name"
};
Was das vorherige Objekt vollständig durch ein neues ersetzte {}
;
2- Ein Ereignis wurde ausgelöst, wie ein Klick oder ähnliches, oder eine der untergeordneten Komponenten hat ein Ereignis ausgelöst.
Veranstaltungen wie:
- Klicken
- Keyup
- Abonnementereignisse
- etc.
Also kurz gesagt:
Verwenden detectChanges()
Sie diese Option, wenn Sie das Modell aktualisiert haben, nachdem Angular die Änderungserkennung ausgeführt hat, oder wenn sich das Update überhaupt nicht in der Winkelwelt befunden hat.
Verwenden markForCheck()
Sie diese Option, wenn Sie OnPush verwenden und das umgehen, ChangeDetectionStrategy
indem Sie einige Daten mutieren, oder wenn Sie das Modell in einem setTimeout aktualisiert haben .