首页 > 解决方案 > Angular 7,Ngrx,ExpressionChangedAfterItHasBeenCheckedError

问题描述

寻找了更长的时间,但找不到任何东西。

我有一个这样的模板:

<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)
});

learning-navigation 的输入是 setter:

  @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,在 ngInit 和 ngAfterChecked 之后强制 detectChanges() (尽管即使它有效,这也不是最佳的)并将它包装在一个容器中,试图将模式直接异步传递到组件中只是用额外的 if 来控制显示。

当前的解决方案有效,并且似乎没有任何副作用,但是无论每次模式更改,它都会引发错误。谢谢

标签: javascriptangulartypescriptngrx

解决方案


您的问题表明 Angular 的更改检测之外的值发生了变化。这可能有多种原因。在您的情况下,我猜这是您输入的异步性质。

如果您的组件是展示组件,您可以将更改检测策略设置为onPush.

这样,您的变更检测器将仅在您的输入有新值时运行

例子:

@Component({
  selector: 'app-your-comp',
  templateUrl: './app-your-comp.component.html',
  styleUrls: ['./app-your-comp.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})

推荐阅读