MatExpansionPanel 表达式在检查错误“mat-expanded: true"后发生了变化 [英] MatExpansionPanel expression has changed after it was checked error 'mat-expanded: true'

查看:14
本文介绍了MatExpansionPanel 表达式在检查错误“mat-expanded: true"后发生了变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an Angular Material Expansion Panel Query list:

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

和一个简单的数组:

questions: [];

扩展面板使用 *ngFor 生成:简化例如:

The Expansion Panels are generated with an *ngFor: simplified for example:

   <ng-container *ngFor="let question of questions>
            <mat-expansion-panel
               ...

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

When I extend the questions array, I want to open up the last expansion panel.

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

        this.questions.push('some-new-item');
      }

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

This works just fine - I insert an item to the array,
the ExpansionPanels get's re-rendered, a new Panel gets created and it actually opens up - my problem is that it generates the following error in the console:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has 
changed after it was checked. Previous value: 'mat-expanded: false'. Current 
value: 'mat-expanded: true'.

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

Is there any way to avoid this?
I have tried using changeDetectorRef and markForCheck() in the subscription, but the error message did not go away (and honestly, I am 100% sure what's the exact problem here).

更新:Stackblitz 问题示例(点击+" 按钮)

推荐答案

来自 角度深度:

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

This is a cautionary mechanism put in place to prevent inconsistencies between model data and UI so that erroneous or old data are not shown to a user on the page.

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

A running Angular application is a tree of components. During change detection Angular performs checks for each component which consists of the following operations performed in the specified order:

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

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

After each operation Angular remembers what values it used to perform an operation. They are stored in the oldValues property of the component view.

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

You might want to trigger the lifecycle hook of your component before the DOM update operation..

这应该对你有用:

你可以为changedetection(cd)添加一个constructor并在change.last.open();

You can add a constructor for changedetection (cd) and call it after 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');
    }
}

这篇关于MatExpansionPanel 表达式在检查错误“mat-expanded: true"后发生了变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆