简体   繁体   English

ExpressionChangedAfterItHasBeenCheckedError:具有两个同级Angular组件

[英]ExpressionChangedAfterItHasBeenCheckedError: with two sibling Angular components

I'm using Angular Material expansion-panel with Flex-Layout and I would like to split my two expansion-panel into two different components. 我正在将Angular Material扩展面板与Flex-Layout一起使用,我想将我的两个扩展面板分成两个不同的组件。

I realized a StackBlitz1 HERE using both expansion-panel in the same component. 我在同一组件中使用两个扩展面板实现了StackBlitz1 HERE On the other hand, in my second StackBlitz2 HERE , I split these two expansion-panels in two different components, but an error occurs. 另一方面,在第二个StackBlitz2 HERE中 ,我将这两个扩展面板拆分为两个不同的组件,但是发生了错误。 The error ExpressionChangedAfterItHasBeenCheckedError appears and it comes from my function "changeExpansionPanelState ()" in the HTML file of my two components. 出现错误ExpressionChangedAfterItHaHasBeenCheckedError,它来自我两个组件的HTML文件中的函数“ changeExpansionPanelState()”。

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

If someone has a solution to be able to do the same thing as my StackBlitz1 with two components, I'm interested. 如果有人有一个解决方案能够通过两个组件完成与StackBlitz1相同的任务,那么我很感兴趣。

DEMO: DEMO:

在此处输入图片说明

Thank you in advance! 先感谢您!

Chellappan's answer is correct, the reason why is below... Chellappan的答案是正确的,原因如下...

Your HTML uses the panelOpenState boolean component variables to control your view... you instantiate these variables with no value when the component is initialized. 您的HTML使用panelOpenState布尔值组件变量来控制您的视图...在初始化组件时,这些实例化变量没有任何值。

  panelOpenState1: boolean;
  panelOpenState2: boolean;

You then set the value to these component variables after the view is rendered via the service subscription... 然后,通过服务订阅呈现视图后,可以将值设置为这些组件变量。

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

So when the view is rendered, for [ngClass]="{'flex': panelOpenState2}" the panelOpenState2 component variable is undefined at this point... but then the subscriptions are created which takes the previous checked value of undefined and replaces it with the observable boolean value. 因此,在呈现视图时,对于[ngClass]="{'flex': panelOpenState2}"panelOpenState2 undefined panelOpenState2组件变量...但是随后创建了订阅,该订阅将使用先前检查的undefined值并将其替换具有可观察的布尔值。

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

The key to avoiding this is to do one of the following... 避免这种情况的关键是执行以下操作之一...

Instantiate your component variables with a value. 用值实例化组件变量。

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

Or create your subscriptions when the component is initialized... before your view is rendered so the component variables are not undefined when the view needs them. 或在初始化组件时创建订阅... 呈现视图之前,以便在需要视图时不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);
  }

I finally changed my method and found a simpler solution to my problem without going through service, here is the result: 我终于改变了方法,找到了一个更简单的解决问题的方法,而无需进行服务,结果如下:

StackBlitz HERE StackBlitz此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM