【问题标题】:How to create a Confirmation Dialog box that can be called from any component in Angular 11?如何创建可以从 Angular 11 中的任何组件调用的确认对话框?
【发布时间】:2021-07-24 15:25:35
【问题描述】:

我在我的 Angular 项目中创建了一个模态作为单独的组件,如下所示:

HTML:

<div mat-dialog-title>
  {{title}}
</div>
<div mat-dialog-content>
  <p>{{message}}</p>
</div>
<div mat-dialog-actions>
  <button mat-button color="primary" (click)="confirm()">{{btnOkText}}</button>
  <button mat-button (click)="decline()" cdkFocusInitial>{{btnCancelText}}</button>
</div>

TS:

export class ConfirmDialogComponent implements OnInit {

  title!: string;
  message!: string;
  btnOkText!: string;
  btnCancelText!: string;

  constructor(
    public dialogRef: MatDialogRef<ConfirmDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: ConfirmDialogModel) {
      // Update view with given values
      this.title = data.title;
      this.message = data.message;
      this.btnOkText = data.btnOkText;
      this.btnCancelText = data.btnCancelText;
    }

  ngOnInit(): void {
  }

  confirm() {
    // Close the dialog, return true
    this.dialogRef.close(true);
  }

  decline() {
    // Close the dialog, return false
    this.dialogRef.close(false);
  }

}

/**
 * Class to represent confirm dialog model.
 *
 * It has been kept here to keep it as part of shared component.
 */
 export class ConfirmDialogModel {

  constructor(
    public title: string,
    public message: string,
    public btnOkText: string,
    public btnCancelText: string) {
  }
}

我创建了一个根注入服务并放入一个初始化并打开对话框的方法,如下所示:

confirmDialog(): void {
    const title = 'Confirmation';
    const message = 'Are you sure you want to do this?';
    const btnOkText = 'Ok';
    const btnCancelText = 'Cancel';

    const dialogData = new ConfirmDialogModel(title, message, btnOkText, btnCancelText);

    const dialogRef = this.dialog.open(ConfirmDialogComponent, {
      maxWidth: "400px",
      data: dialogData
    });

    dialogRef.afterClosed().subscribe(dialogResult => {
      dialogResult;
    });
}

如果我console.log(dialogResult)我会得到正确的结果(真/假)

所有这一切都很好,但是,我想将这个 dialogResult 变成一个可观察的对象,任何组件都会调用我的确认服务,看到 dialogResult 然后基于它执行操作。

例子:

我有一个 home 组件,我将 confirmService 注入其中

constructor(private confirmService : ConfirmService) {}

然后,在 home.html 中,我创建了一个带有 (click) 事件的按钮,如下所示:

<button mat-raised-button color="primary" (click)="confirm()">Confirm</button>

confirm()函数如下:

confirm() {
    this.confirmService.confirmDialog();
}

我希望能够订阅confirmDialog() 并从中获取结果,我该怎么做?

【问题讨论】:

    标签: angular angular-material


    【解决方案1】:

    使用这个解决方案StackBlitz它可以从任何打字稿文件中调用,而不需要 HTML 选择器。我建议您创建一个服务并像本示例中那样放置一个确认框,这样当您想调用它时,只需调用带有返回可观察的文本和颜色类型参数的服务方法。

    您可以使用这个角度确认框生成器来测试https://costlydeveloper.github.io/ngx-awesome-popup/#/playground/confirm-box-generator

    
         openConfirmBox() {
            const newConfirmBox = new ConfirmBoxInitializer();
    
            newConfirmBox.setTitle('Title');
            newConfirmBox.setMessage('Your message!');
    
            // Choose layout color type
            newConfirmBox.setConfig({
            LayoutType: DialogLayoutDisplay.SUCCESS, // SUCCESS | INFO | NONE | DANGER | WARNING
            });
    
            // Simply open the ConfirmBox
            newConfirmBox.openConfirmBox$(); // subscribe to get button clicked response
        }
    
    

    这是我的个人工作,我编写了一个类似于 mat dialog 但略有不同的完整对话框系统,具有更多支持多个对话框的功能,在后台添加了令牌功能,因此开发人员可以按时间顺序调用对话框上方的对话框,按钮带有 observables 的生成器,等等。此外,它还为使用相同技术的确认框、toast 消息和 cookie 横幅提供了完整的解决方案。

    后来我稍微努力了一下,放到了开源库中,想和社区分享。 通过给 Github repo 打一颗星来支持它。我希望你会发现它有用。

    https://github.com/costlydeveloper/ngx-awesome-popup

    【讨论】:

      【解决方案2】:

      像这样把它包裹在 observable 中

      confirmDialog(): Observable<boolean> {
          return new Observable(observer => {
            ...
            dialogRef.afterClosed().subscribe(dialogResult => {
              observer.next(dialogResult);
              observer.complete(); //to avoid memory leaks
            });
          });
      }
      

      或者简单地返回afterClosed,因为它是一个可观察对象,将其转换为布尔值。

      confirmDialog(): Observable<boolean> {
          ...
          return dialogRef.afterClosed() as Observable<boolean>;
      }
      

      然后像这样订阅

      confirm() {
          this.confirmService.confirmDialog().subscribe(isConfirmed => {
            console.log(isConfirmed);
          })
      }
      

      【讨论】:

      • 如果你只输入return dialogRef.afterClosed();。够吗?
      • 谢谢@Sameer!是的,.next 将适用于我的情况。
      • @robert 是的,这就足够了,答案已更新。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      相关资源
      最近更新 更多