MatExpansionPanel 表达式在检查错误“mat-expanded: true”后发生了变化

For*_*stG 5 angular-material angular

我有一个 Angular Material Expansion Panel 查询列表:

  @ViewChildren(MatExpansionPanel)
  matExpansionPanelQueryList: QueryList<MatExpansionPanel>;
Run Code Online (Sandbox Code Playgroud)

和一个简单的数组:

questions: [];
Run Code Online (Sandbox Code Playgroud)

扩展面板是用*ngFor: 简化生成的,例如:

   <ng-container *ngFor="let question of questions>
            <mat-expansion-panel
               ...
Run Code Online (Sandbox Code Playgroud)

当我扩展问题数组时,我想打开最后一个扩展面板。

     extendQuestion() {
        this.matExpansionPanelQueryList.changes.subscribe(
          change => {
            change.last.open();
          }
        );

        this.questions.push('some-new-item');
      }
Run Code Online (Sandbox Code Playgroud)

这工作得很好 - 我向数组中插入了一个项目,
重新渲染了 ExpansionPanels,创建了一个新面板并且它实际上打开了 - 我的问题是它在控制台中生成以下错误:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has 
changed after it was checked. Previous value: 'mat-expanded: false'. Current 
value: 'mat-expanded: true'.
Run Code Online (Sandbox Code Playgroud)

有什么办法可以避免这种情况吗?
我曾尝试在订阅中使用changeDetectorRefmarkForCheck(),但错误消息并没有消失(老实说,我 100% 确定这里的确切问题是什么)。

更新:问题的Stackblitz 示例(单击“+”按钮)

iLu*_*gix 7

angularindepth

这是一种预防机制,旨在防止模型数据和 UI 之间出现不一致,从而不会在页面上向用户显示错误或旧数据。

运行中的 Angular 应用程序是一棵组件树。在变更检测期间,Angular 对每个组件执行检查,其中包含按指定顺序执行的以下操作:

  • 更新所有子组件/指令的绑定属性
  • 在所有子组件/指令上调用 ngOnInit、OnChanges 和 ngDoCheck 生命周期钩子
  • 更新当前组件的 DOM
  • 为子组件运行更改检测
  • 为所有子组件/指令调用 ngAfterViewInit 生命周期钩子

在每次操作之后,Angular 都会记住它用于执行操作的值。它们存储在组件视图的 oldValues 属性中。

您可能希望在 DOM 更新操作之前触发组件的生命周期钩子。

这应该对你有用:

您可以添加一个 constructor for changedetection (cd) 并在之后调用它change.last.open();

import {ChangeDetectorRef, Component, OnInit, QueryList, ViewChildren} from '@angular/core';

import {MatDialog, MatExpansionPanel} from '@angular/material';

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})

export class AppComponent {
questions = ['first', 'second'];

constructor(private cd: ChangeDetectorRef) {
    }

@ViewChildren(MatExpansionPanel) matExpansionPanelQueryList: QueryList<MatExpansionPanel>;


extendQuestion() {
        this.matExpansionPanelQueryList.changes.subscribe(
        change => {
            change.last.open();
            this.cd.detectChanges();
        }
        );
        this.questions.push('some-new-item');
    }
}
Run Code Online (Sandbox Code Playgroud)