javascript - Angular 7, Ngrx, ExpressionChangedAfterItHasBeenCheckedError
căuta de mai mult timp, dar nu a găsit nimic.
Am un șablon astfel:
<learning-navigation *ngIf="(_navigationSelectedSafe$ | async) == _navigationLayout.location" [(selectMode)]="_navigationModeSelected"></learning-navigation>
Unde :
private _navigationSelected$: Observable<string>;
private _navigationSelectedSafe$ = new EventEmitter<any>(true);
...
this._navigationSelected$.subscribe(res => {
...
this._navigationSelectedSafe$.emit(res)
});
cu intrarea de învățare-navigare fiind un seter:
@Input()
set selectMode(mode: number) {
this.mode = mode;
}
Acest lucru cauzează eroarea:
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'selectMode: null'. Current value: 'selectMode: 1'.
Am încercat deja să schimb EventEmitter cu un BehaviourSubject, forțând detectChanges() după ngInit și ngAfterChecked (deși acest lucru nu ar fi optim nici măcar dacă ar funcționa) și, de asemenea, să-l înfășor într-un container încercând să trec modul direct asincron în componentă, controlând afișarea doar cu un if suplimentar.
Soluția actuală funcționează și nu pare să existe vreun efect secundar, dar aruncă eroarea în continuare de fiecare dată când se schimbă modul. Mulțumesc
Răspuns #1
Problema ta indică faptul că a avut loc o schimbare de valoare în afara detectării schimbărilor Angular. Acest lucru se poate întâmpla din mai multe motive. În cazul tău, presupun că este natura asincronă a inputului tău.
Dacă componenta dvs. este o componentă de prezentare, puteți seta strategia de detectare a modificărilor la onPush.
În acest fel, detectorul de modificări va rula doar atunci când există o valoare nouă pe intrarea ta
exemplu :
@Component({
selector: 'app-your-comp',
templateUrl: './app-your-comp.component.html',
styleUrls: ['./app-your-comp.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
Răspunsul #2
<ng-container *ngIf="_navigationSelectedSafe$ | async as selectedSafe">
<learning-navigation *ngIf="selectedSafe == _navigationLayout.location"
[(selectMode)]="_navigationModeSelected"></learning-navigation>
</ng-container>
Acest lucru va preveni afișarea elementului learning-navigation atunci când valoarea observabilului tău este nulă, eliminând astfel eroarea ta.
EDITEAZĂ
Folosește un timeout în seterul tău pentru a rezolva orice altă problemă :
@Input()
set selectMode(mode: number) {
setTimeout(() => this.mode = mode);
}
