【问题标题】:Open several mat-dialogs one by one after the previous one is closed在前一个关闭后一个一个打开几个 mat-dialogs
【发布时间】:2021-02-04 04:05:15
【问题描述】:

在我的代码中,我有一个按钮,可以浏览数据列表并为每个数据打开一个mat-dialog

不幸的是,在循环过程中,所有mat-dialogs 都打开了。

我希望通过使用 dialogRef.afterClosed() 方法,根据结果 (true) 下一个 mat-dialog 打开或 (false) 循环结束。

openDialog(): void {
  this.data.forEach(data => {
    const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
      disableClose: true
    });
    dialogRef.componentInstance.data = data;

    dialogRef.afterClosed().subscribe(result => {
      if (result) {
        // open next mat-dialog
      } else {
        // stop loop
      }
    });
  });
}

<div mat-dialog-actions>
  <button mat-button (click)="_dialogRef.close(true)">Ok</button>
  <button mat-button (click)="_dialogRef.close(false)">Cancel</button>
</div>

StackBlitz Here

我该怎么做?我不知道该怎么做。

感谢您的帮助。

【问题讨论】:

    标签: angular typescript rxjs angular-material mat-dialog


    【解决方案1】:

    您可以通过将您的方法标记为async 并等待您的对话afterClosed() 调用来实现此目的,但由于await 仅适用于promise,您需要将Observable 转换为Promise

    这是一个适合我的解决方案

    @Component({
      selector: "dialog-overview-example",
      templateUrl: "dialog-overview-example.html",
      styleUrls: ["dialog-overview-example.css"]
    })
    export class DialogOverviewExample {
      data: any[] = DATA;
      constructor(public dialog: MatDialog) {}
    
      async openDialog() {
    
      for(var i =0; i < this.data.length; i++) {
        const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
            disableClose: true
          });
          dialogRef.componentInstance.data = this.data[i];
          var result = await  dialogRef.afterClosed().toPromise();
            if (!result) {
              console.log("Stop loop", result);
              break;
            }
            // else continue the loop
    
       }
     }
    }
    

    Stackblitz Working Demo

    【讨论】:

      【解决方案2】:

      你可以通过 rxjs takeWhile 来实现这个

      from(this.data)
            .pipe(
              concatMap(x => {
                const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
                  disableClose: true
                });
      
                dialogRef.componentInstance.data = x;
      
                return dialogRef.afterClosed();
              }),
              takeWhile(Boolean)
            ).subscribe();
      

      https://stackblitz.com/edit/open-mat-dialogs-one-by-one-after-the-previous-one-is-cl-yqprmt?file=src/app/dialog-overview-example.ts

      【讨论】:

      • 非常感谢您的解决方案,在我的原始代码中,我使用的是列表列表 (new StackBlitz),我似乎无法使用列表列表设置您的解决方案,您可以帮帮我?
      • 把数组拉平stackblitz.com/edit/…
      【解决方案3】:

      我建议不要使用迭代器(foreach)(事实上,我不鼓励使用),而是如果还有更多数据要显示,则在订阅中再次触发openDialog(类似队列的方法) .当然,这需要从列表中删除显示的数据,但同时也允许将新数据附加到列表中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-28
        • 2020-09-17
        • 2018-07-20
        • 1970-01-01
        • 1970-01-01
        • 2013-12-09
        相关资源
        最近更新 更多