首页 > 解决方案 > ExpressionChangedAfterItHasBeenCheckedError:带有两个同级 Angular 组件

问题描述

我正在使用带有 Flex-Layout 的 Angular Material 扩展面板,我想将我的两个扩展面板分成两个不同的组件。

我在同一个组件中使用两个扩展面板实现了StackBlitz1 HERE 。另一方面,在我的第二个StackBlitz2 HERE中,我将这两个扩展面板拆分为两个不同的组件,但出现了错误。出现错误 ExpressionChangedAfterItHasBeenCheckedError,它来自我的两个组件的 HTML 文件中的函数“changeExpansionPanelState()”。

<mat-expansion-panel (opened)="changeExpansionPanelState()"
                     (closed)="changeExpansionPanelState()">
  ...
</mat-expansion-panel>

如果有人有一个解决方案可以用两个组件做与我的 StackBlitz1 相同的事情,我很感兴趣。

演示:

在此处输入图像描述

先感谢您!

标签: angularrxjsangular-materialpanelsiblings

解决方案


Chellappan 的回答是正确的,原因如下...

您的 HTML 使用panelOpenState布尔组件变量来控制您的视图......当组件初始化时,您实例化这些变量时没有值。

  panelOpenState1: boolean;
  panelOpenState2: boolean;

然后,在通过服务订阅呈现视图后,将值设置为这些组件变量...

 ngAfterViewInit() {
    this.panelState.panelOpenState1$.subscribe(panelOpenState1 => this.panelOpenState1 = panelOpenState1);
    this.panelState.panelOpenState2$.subscribe(panelOpenState2 => this.panelOpenState2 = panelOpenState2);
  }

因此,当呈现视图时,[ngClass]="{'flex': panelOpenState2}"组件panelOpenState2变量就undefined在这一点上......但是随后创建了订阅,该订阅采用先前检查的值undefined并将其替换为可观察的布尔值。

Previous value: 'flex: undefined'. Current value: 'flex: true'

避免这种情况的关键是执行以下操作之一...

用一个值实例化你的组件变量。

export class FirstPanelComponent implements AfterViewInit {
  panelOpenState1: boolean = true;
  panelOpenState2: boolean = false;

或者在组件初始化时创建订阅......您的视图呈现之前,因此组件变量不在undefined视图需要它们时。

  ngOnInit(){
    this.panelState.panelOpenState1$.subscribe(panelOpenState1 => this.panelOpenState1 = panelOpenState1);
    this.panelState.panelOpenState2$.subscribe(panelOpenState2 => this.panelOpenState2 = panelOpenState2);
  }

  ngAfterViewInit() {
    // this.panelState.panelOpenState1$.subscribe(panelOpenState1 => this.panelOpenState1 = panelOpenState1);
    // this.panelState.panelOpenState2$.subscribe(panelOpenState2 => this.panelOpenState2 = panelOpenState2);
  }

推荐阅读