MatExpansionPanel表达式在检查错误后已更改'mat-expanded:true' [英] MatExpansionPanel expression has changed after it was checked error 'mat-expanded: true'

查看:138
本文介绍了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,创建了一个新的Panel,它实际上打开了-我的问题是它在控制台中生成以下错误:

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..

这应该对您有用:

您可以添加constructor进行变更检测(cd),并在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天全站免登陆