Ausdruck ___ hat sich geändert, nachdem es überprüft wurde
Warum ist die Komponente, die in diesem einfachen plunk
@Component({
selector: 'my-app',
template: `<div>I'm {{message}} </div>`,
})
export class App {
message:string = 'loading :(';
ngAfterViewInit() {
this.updateMessage();
}
updateMessage(){
this.message = 'all done loading :)'
}
}
werfen:
AUSNAHME: der Ausdruck 'ich bin {{message}} in App@0:5' hat sich geändert, nachdem es überprüft wurde. Vorheriger Wert: "ich bin be -: ( '. Aktueller Wert: "ich bin ganz fertig-laden :)' in [ich bin {{message}} in App@0:5]
als alle, die ich Tue, ist die Aktualisierung eine einfache Bindung, wenn meine Ansicht eingeleitet wird?
Der Artikel Alles, was Sie wissen müssen über die
ExpressionChangedAfterItHasBeenCheckedError
Fehler erklärt das Verhalten in großen details.InformationsquelleAutor awqueous | 2015-12-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie gesagt um drewmoore, die richtige Lösung in diesem Fall ist manuell auslösen (change detection) für die aktuelle Komponente. Dies geschieht mit Hilfe der
detectChanges()
Methode derChangeDetectorRef
Objekt (importiert ausangular2/core
), oder seinemarkForCheck()
- Methode, die macht auch alle übergeordneten Komponenten zu aktualisieren. Relevante Beispiel:Hier sind auch Plunkers Nachweis der ngOnInit, setTimeout, und enableProdMode Ansätze nur für den Fall.
Wo ist Ihre Erklärung für den cdr-Eigenschaft? Ich würde erwarten, um zu sehen, eine Zeile wie
cdr : any
oder etwas ähnliches unter diemessage
Erklärung. Nur besorgt, hab ich was verpasst?es ist in der Konstruktor-Argumente.
Dieser resolution fix mein problem! Vielen Dank! Sehr klare und einfache Weise.
Das half mir - mit ein paar Modifikationen. Ich hatte zu Stil li-Elemente generiert wurden, die über ngFor Schleife. Ich brauchte, um zu ändern die Farbe von Spannweiten innerhalb der Liste Elemente basierend auf innerText auf die Schaltfläche 'Sortieren', die aktualisiert einen bool als parameter eine Art Rohr (das sortierte Ergebnis war eine Kopie der Daten, so dass Stile waren nicht immer aktualisiert mit ngStyle allein). - Anstatt 'AfterViewInit', die ich verwendet, 'AfterViewChecked' - von mir aus auch sicher, dass import und implementieren AfterViewChecked. Hinweis: Einstellung der pipe zu 'rein: false,' war nicht die Arbeit, die ich hatte, um diesen zusätzlichen Schritt (:
InformationsquelleAutor Tycho
Beachten Sie zunächst, dass diese exception wird nur geworfen werden, wenn Sie Ihre app im dev-Modus (was standardmäßig der Fall ist, wie der beta-0): Wenn Sie anrufen
enableProdMode()
beim bootstrapping der app, es wird nicht geworfen (siehe aktualisierte plunk).Zweite, nicht, dass, weil diese Ausnahme wird geworfen, aus gutem Grund: In kurzen, wenn in den dev-Modus jede Runde, die der Erkennung von änderungen ist unmittelbar gefolgt von einer zweiten Runde, die überprüft, keine Bindungen haben sich geändert seit dem Ende des ersten, so würde dies darauf hinweisen, dass änderungen, die hervorgerufen werden durch die change detection selbst.
In Ihrem plunk, die Bindung
{{message}}
geändert durch Eure Berufung zusetMessage()
ist, was geschieht in derngAfterViewInit
Haken, der Auftritt als Teil der Erstausbildung (change detection) aktivieren. Das ist an sich nicht problematisch, obwohl - das problem ist, dasssetMessage()
änderungen der verbindlich, aber nicht auslösen einer neuen Runde von change-detection, was bedeutet, dass diese änderung nicht erkannt werden, bis einige zukünftige Runde von change-detection ausgelöst wird woanders.Den mitnehmen: Alles, verpasst eine Bindung muss zum auslösen einer Runde von change-detection -, wenn es funktioniert.
Update in Reaktion auf alle Anfragen für ein Beispiel, wie zu tun, dass: @Tycho ' s Lösung funktioniert, wie die drei Methoden in die Antwort @MarkRajcok hingewiesen. Aber ehrlich gesagt, Sie alle fühlen sich hässlich und falsch für mich, wie die Art von hacks haben wir genutzt, um sich auf in der ng1.
Sicher sein, es gibt gelegentliche Umstände, in denen diese hacks sind, aber wenn Sie sind mit Ihnen auf etwas mehr als ein sehr gelegentlichen basis, es ist ein Zeichen, dass Sie kämpfen den Rahmen nicht vollständig umarmen Sie Ihre reaktive Natur.
IMHO, mehr Redewendungen, "Angular2 Weg", dies zu erreichen, ist etwas entlang der Linien von: (plunk)
dass die änderungen eine verbindliche Anforderungen zum auslösen einer Runde von change-detection-wenn es funktioniert". Wie? Es ist eine gute Praxis? Sollte nicht alles abgeschlossen werden, in einem einzigen Lauf?
in der Tat. Da schrieb ich diesen Kommentar, den ich beantwortet habe noch eine Frage, wo ich beschreibe die 3 Wege zu laufen, change detection, das beinhaltet
detectChanges()
.nur der Hinweis, dass in der aktuellen Frage Körper, die aufgerufene Methode benannt ist
updateMessage
, nichtsetMessage
Ich hatte das gleiche Gefühl, bis ich Lesen Sie den blog in Kommentar unter der Frage: blog.angularindepth.com/... Es erklärt, warum muss dies manuell getan. In diesem Fall, angular change-detection hat einen Lebenszyklus. Im Falle, dass sich etwas verändert einen Wert zwischen diesen Lebenszyklen, dann ein konsequenter change-detection ausgeführt werden muss (oder eine settimeout - führt in der next-event-Schleife, die Auslösung der change-detection-wieder).
InformationsquelleAutor awqueous
Ich behoben durch hinzufügen ChangeDetectionStrategy kantige Kern.
Hmm... Dann der Wechsel Detektor-Modus wird zunächst
CheckOnce
(Dokumentation)InformationsquelleAutor Biranchi
Können Sie nicht verwenden
ngOnInit
weil Sie nur die änderung der member-variablemessage
?Wenn Sie Zugriff auf einen Verweis auf eine Kind-Komponente
@ViewChild(ChildComponent)
Sie wirklich brauchen, zu warten, bis es mitngAfterViewInit
.Einen dirty fix ist, rufen Sie die
updateMessage()
im nächsten event-Schleife mit z.B. setTimeout.Dies sollte der apt-Antwort. es funktioniert.
InformationsquelleAutor Jo VdB
ngAfterViewChecked() für mich gearbeitet:
InformationsquelleAutor Jaswanth Kumar
Den Artikel Alles, was Sie wissen müssen über die
ExpressionChangedAfterItHasBeenCheckederror
- Fehler erklärt das Verhalten in großen details.Das problem mit der Einstellung ist, dass
ngAfterViewInit
lifecycle-hook wird ausgeführt, wenn der change detection verarbeitet DOM-updates. Und Sie sind effektiv beim ändern der Eigenschaft, die verwendet wird in der Vorlage in dieser Haken bedeutet, dass die DOM muss neu gerendert:und dies erfordert ein anderes change-detection-Zyklus-und winkelversatz von design läuft nur eine digest-Zyklus.
Haben Sie grundsätzlich zwei alternativen, wie es zu beheben:
aktualisieren Sie die Eigenschaft asynchron entweder mit
setTimeout
,Promise.then
oder asynchrone beobachtbaren auf die in der Vorlageführen Sie die Eigenschaft update in einen Haken vor dem DOM-update - ngOnInit, ngDoCheck, ngAfterContentInit, ngAfterContentChecked.
InformationsquelleAutor Max Koretskyi aka Wizard
Müssen Sie nur aktualisieren Sie Ihre Nachricht in die richtige lifecycle-Haken, in diesem Fall ist
ngAfterContentChecked
stattngAfterViewInit
, weil in ngAfterViewInit einen Scheck für die variable Nachricht wurde begonnen, ist aber noch nicht zu Ende.finden Sie unter:
https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#afterview
so wird der code nur:
sehen die arbeiten demo auf Plunker.
@ViewChildren()
Länge-Zähler die war bevölkert von einer Beobachtbaren. Dies war die einzige Lösung, die für mich gearbeitet!Kombination von
ngAfterContentChecked
undChangeDetectorRef
von oben für mich gearbeitet. AufngAfterContentChecked
genannt -this.cdr.detectChanges();
InformationsquelleAutor RedPelle
Dafür habe ich versucht, über viele Antworten funktioniert nicht in der neuesten version von Eckig (6 oder später)
Ich bin mit Material-Kontrolle, dass die erforderlichen änderungen, die nach der ersten Bindung getan.
Hinzufügen meine Antwort so, dies hilft, einige lösen Problem.
InformationsquelleAutor MarmiK
Können Sie auch die Aufruf updateMessage() in der ngOnInt()-Methode, zumindest klappt es bei mir
In der RC1 das löst keine Ausnahme
InformationsquelleAutor Tobias Gassmann
Es wirft einen Fehler, da der code aktualisiert, wenn ngAfterViewInit() genannt wird. Bedeutet, dass Ihre anfänglichen Wert wurde verändert, wenn ngAfterViewInit nehmen Sie Platz, Wenn Sie Sie nennen, in ngAfterContentInit() dann wird es kein Fehler.
InformationsquelleAutor Sandip - Full Stack Developer
Können Sie auch einen timer mit der rxjs
Observable.timer
Funktion, und aktualisieren Sie dann die Nachricht in Ihrem Abonnement:InformationsquelleAutor rabinneslo
Konnte ich nicht kommentieren @Biranchi s post, da ich nicht genügend Ruf hat, aber es behoben das problem für mich.
Eine Sache zu beachten!
Wenn das hinzufügen changeDetection: ChangeDetectionStrategy.OnPush auf die Komponente nicht funktioniert, und das ist eine untergeordnete Komponente (dumme Komponente) versuchen, indem es die Eltern auch.
Dieser Fehler wurde behoben, aber ich Frage mich, was sind die Nebenwirkungen von diesem.
InformationsquelleAutor TKDev