You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Material 16对话框在API请求完成前关闭问题排查与解决

问题原因

按钮上同时绑定了[mat-dialog-close]="true"和(click)="deleteRecords()",Angular事件处理的优先级中,mat-dialog-close指令的关闭逻辑会先于组件的click事件执行。这就导致对话框在deleteRecords()里的forkJoin请求还未处理完成时就已关闭,afterClosed()回调被提前触发,里面的#setFirstTablePage()和resetCheckboxes()先执行,而对话框内的API请求才刚刚发起。

解决方案

移除按钮上的[mat-dialog-close]="true",完全通过deleteRecords()方法里的dialogRef.close()控制对话框关闭时机,确保只有当forkJoin的所有API请求完成后,才关闭对话框并触发afterClosed()回调。

修改后的代码示例

按钮代码

<button
  mat-raised-button
  cdkFocusInitial
  (click)="deleteRecords()"
  color="accent">DELETE RECORDS</button>

对话框组件代码(仅调整close传参,逻辑不变)

@Component({                                                                                  
  selector: 'delete-records-dialog',                                                                                  
  templateUrl: 'delete-records-dialog.html',                                                                                  
})                                                                                  
export class DeleteRecordsDialog {                                                                                  
  recordsToDelete: Array<object>;                                                                                  
                                                                                    
  constructor(                                                                                  
    @Inject(MAT_DIALOG_DATA) public data: {                                                                                  
      recordsToDelete: Array<object>,                                                                                  
    },                                                                                  
    private apiService: ApiService,                                                                                  
    private dialogRef: MatDialogRef<DeleteRecordsDialog>,                                                                                  
  ) {                                                                                  
    this.recordsToDelete = data.recordsToDelete;                                                                                  
  }                                                                                  
                                                                                    
  deleteRecords() {                                                                                  
    const httpReuests = this.recordsToDelete.map((id) => (                                                                                  
      this.apiService.deleteRecord(id)                                                                                  
    ));                                                                                  
                                                                                    
    const complete = () => {                                                                                  
      this.dialogRef.close(true); // 传入true,和原mat-dialog-close的返回值保持一致
    }                                                                                  
                                                                                    
    forkJoin(httpReuests).subscribe({ complete });                                                                                  
  }                                                                                  
}

打开对话框代码(无需修改)

openConfirmDialog() {
  const { recordsToDelete } = this;
  const dialogRef = this.dialog.open(DeleteRecordsDialog, {
    data: { recordsToDelete }
  });                                                                                  
                                                                                
  dialogRef.afterClosed().subscribe((isSubmit) => {                                                                                  
    if (isSubmit) {                                                                                  
      this.#setFirstTablePage();                                                                                  
      this.resetCheckboxes();                                                                                  
    }                                                                                  
  });                                                                                  
}  

修改后,点击按钮会先执行deleteRecords(),等待forkJoin所有请求完成后,才会调用dialogRef.close(true)关闭对话框,此时afterClosed()回调才会触发,里面的操作也会在API请求完成后执行。

内容的提问来源于stack exchange,提问作者dman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 17:33:18