Angular 7, Ngrx, ExpressionChangedAfterItHasBeenCheckedError - PullRequest
0 голосов
/ 19 июня 2019

долго искал, но ничего не мог найти.

У меня есть такой шаблон:

<learning-navigation *ngIf="(_navigationSelectedSafe$ | async) == _navigationLayout.location" [(selectMode)]="_navigationModeSelected"></learning-navigation>

Где:

private _navigationSelected$: Observable<string>;
private _navigationSelectedSafe$ = new EventEmitter<any>(true);

...

this._navigationSelected$.subscribe(res => {
  ...
  this._navigationSelectedSafe$.emit(res)
});

с вводом обучающей навигации как установщика:

  @Input()
  set selectMode(mode: number) {
    this.mode = mode;
  }

Это вызывает ошибку:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'selectMode: null'. Current value: 'selectMode: 1'. 

Я уже пытался изменить EventEmitter на BehaviourSubject, принудительно вызывая detectChanges () после ngInit и ngAfterChecked (хотя это не было бы оптимальным, даже если бы это работало), а также оборачивая его в контейнере, пытаясь передать режим напрямую в асинхронный режим компонент, просто управляя дисплеем с дополнительным, если.

Текущее решение работает, и, похоже, никаких побочных эффектов нет, но оно выдает ошибку независимо от того, когда режим меняется. Спасибо

Ответы [ 2 ]

3 голосов
/ 19 июня 2019

Ваша проблема указывает на то, что произошло изменение значения за пределами обнаружения изменений Angular.Это может произойти по нескольким причинам.В вашем случае это асинхронный характер вашего ввода, я думаю.

Если ваш компонент представляет собой презентационный компонент, вы можете установить стратегию обнаружения изменений на onPush.

Таким образом, ваш детектор изменений будет работать только при наличии нового значения на вашем входе

пример:

@Component({
  selector: 'app-your-comp',
  templateUrl: './app-your-comp.component.html',
  styleUrls: ['./app-your-comp.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
0 голосов
/ 19 июня 2019
<ng-container *ngIf="_navigationSelectedSafe$ | async as selectedSafe">
  <learning-navigation *ngIf="selectedSafe == _navigationLayout.location" 
    [(selectMode)]="_navigationModeSelected"></learning-navigation>
</ng-container>

Это предотвратит отображение элемента learning-navigation, когда значение вашей наблюдаемой величины равно нулю, тем самым стирая вашу ошибку.

EDIT

Используйте тайм-аут в вашем сеттере для решения любой дальнейшей проблемы:

@Input()
set selectMode(mode: number) {
  setTimeout(() => this.mode = mode);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...