在检查后,表达式发生了变化 - MatDialog Angular 6

11

我已经阅读了几篇答案并尝试了许多方法,但似乎无法使其正常工作。在我的Angular 6应用程序中,我尝试打开MatDialog,但是我收到以下错误:

ERROR Error:
ExpressionChangedAfterItHasBeenCheckedError:
表达式在检查后已发生更改。之前的值:'@slideDialog: enter'。当前值:'@slideDialog: exit'。

当我调试应用程序并单击结账按钮时,MatDialog会打开,然后在执行几行代码后关闭。在不使用断点运行应用程序时,您根本看不到对话框打开。

这是模板文件:

<div>
  <button id="cancelButton" mat-raised-button (click)="clearCart()">Cancel</button>
  <button id="checkoutButton" mat-raised-button color="primary" (click)="openCheckoutDialog(dataSource)" [disabled]="isTableEmpty()">Checkout</button>
</div>

当我点击ID为“checkoutButton”的按钮时,它调用openCheckoutDialog()

这是调用openCheckoutDialog的我的类:

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

@Component({
  selector: 'app-shopping-cart',
  templateUrl: './shopping-cart.component.html',
  styleUrls: ['./shopping-cart.component.css']
})
export class ShoppingCartComponent implements OnInit {

  dataSource: MatTableDataSource<Item>;
  itemList: Item[] = [];

  constructor(public dialog: MatDialog, private cdr: ChangeDetectorRef) { }

  openCheckoutDialog(): void {
    const dialogRef = this.dialog.open(ReviewItemListComponent, {
      width: '250px',
      data: this.itemList
    });
    // this.cdr.detectChanges();

    dialogRef.afterClosed().subscribe(result => {
      console.log(`Dialog result: ${result}`);
    });
    // this.cdr.detectChanges();
  }
}

我已经在上述两个地方尝试使用this.cdr.detectChanges(),但我仍然收到错误信息。

这是我的ReviewItemListComponent模板(当结账按钮被点击时弹出对话框):

<div>
  <h1 mat-dialog-title>
    Are you sure?
  </h1>

  <mat-dialog-actions>
    <button tabindex="-1" mat-raised-button [mat-dialog-close]="true">Cancel</button>
    <button tabindex="-1" mat-raised-button color="primary" (click)="confirm()">Confirm</button>
  </mat-dialog-actions>
</div>

这里是ReviewItemListComponent类:

import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { Item } from '../item';

@Component({
  selector: 'app-review-item-list',
  templateUrl: './review-item-list.component.html',
  styleUrls: ['./review-item-list.component.css']
})
export class ReviewItemListComponent implements OnInit {

  constructor(public dialogRef: MatDialogRef<ReviewItemListComponent>,
    @Inject(MAT_DIALOG_DATA) public data: Item[]) { }

  ngOnInit() {
    this.dialogRef.close();
  }

  confirm(): void {
    this.dialogRef.close();
  }

}

我没有对数据做任何更改,这也是大多数问题和答案所涉及的内容,那么我该如何解决打开MatDialog的问题?

编辑:

事实证明,我把this.dialogRef.close()粘贴到了错误的方法中。在这种情况下,我把它放在了ngOnInit()中,当我创建我的review-item-list-component.ts文件时。所以一旦打开它,我就关闭它。这仍然无法解释错误。关闭最近打开的对话框在ngOnInit()内有什么问题?


奇怪 - 这些是动画属性。请检查该库是否与NG6兼容。 - bc1105
最近有人提交了一个相似的问题,链接在此:https://github.com/angular/material2/issues/10705。我认为这实际上与此问题相关:https://github.com/angular/angular/issues/15634。解决方法似乎是将对话框创建包含在setTimeout中。 - Michael Doye
@bc1105请查看我问题的编辑部分。 - Michael
@Und3rTow 我已经尝试了超时,可以看看我编辑后的问题。 - Michael
ngOnInit 中关闭对话框本身并没有什么本质的问题。问题在于视图(对话框)在变更检测周期中被修改了。(在开发模式下会运行两次 - 在生产环境中不会出现此错误)如果你将 dialog.close() 移动到 ngAfterViewInit 中,我相信它应该可以避免抛出该错误。 - Michael Doye
99%的“ExpressionChangedAfterItHasBeenCheckedError”错误可以通过在父级上添加“changeDetectionRef.detectChanges()”来解决。 - Stavm
3个回答

7

使用setTimeout内的dialog close。

setTimeout(() => {    
    this.dialogRef.close();
}, 0);

2
我知道你的问题可能已经不再实际,但我仍然会回答。问题在于你在ngOnInit函数中调用了close方法。
当你调用close方法时,组件尚未完成初始化,此时会出现错误。
请在ngOnInit中删除这个调用,并编写正确的逻辑,即编写一个单独的方法来调用close方法,在需要的地方调用它。
谢谢。

2

[mat-dialog-close][matDialogClose]更改为(click)事件。这对我有用。

更新:我猜[matDialogClose]现在已经按我们的期望工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接