【问题标题】:How to close a mat dialog without a backdrop on clicking outside?如何在没有背景的情况下关闭垫子对话框?
【发布时间】:2019-09-12 00:24:49
【问题描述】:

如何通过单击外部来关闭 stackblitz example (最小的、可重现的示例。) 中的对话框?

如果我删除属性hasBackdrop: false -> Working Stackblitz Example

【问题讨论】:

    标签: angular angular-material material-dialog


    【解决方案1】:

    创建Angular Material Dialog 在对话框外单击时关闭(同时创建没有背景的外观)的标准方法是使用内置库 CSS 类 cdk-overlay-transparent-backdrop 并使用 @ 987654322@财产backdropClass

    openDialog 方法是:

    openDialog(): void {
      const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
        backdropClass: 'cdk-overlay-transparent-backdrop',
        hasBackdrop: true,
        width: '250px'
      });
    }
    

    Stackblitz Example

    【讨论】:

    • 这与 kevits 的回答相同。如果我这样做,我必须在按钮上单击两次以关闭背景一次以单击按钮
    • 不,我的意思是如果页面上有按钮,现在您必须单击按钮两次才能关闭背景,然后才能实际单击按钮。这是有缺陷的行为
    【解决方案2】:

    简而言之,您需要进行自己的点击处理 - 聆听点击并确定它们是否在对话框之外。这使您不会像背景一样捕获点击事件。 Here's a StackBlitz example 基于你的:

    @Component({
      selector: 'dialog-overview-example',
      templateUrl: 'dialog-overview-example.html',
      styleUrls: ['dialog-overview-example.css'],
    })
    export class DialogOverviewExample {
    
      @HostListener('document:click', ['$event'])
      clickout(event) {
        if (this.clickoutHandler) {
          this.clickoutHandler(event);
        }
      }
    
      animal: string;
      name: string;
    
      clickoutHandler: Function;
    
      dialogRef: MatDialogRef<DialogOverviewExampleDialog>;
    
      constructor(public dialog: MatDialog) {}
    
      openDialog(): void {
        setTimeout(() => {
          this.dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
            width: '250px',
            hasBackdrop: false
          });
    
          this.dialogRef.afterOpened().subscribe(() => {
            this.clickoutHandler = this.closeDialogFromClickout;
          });
    
          this.dialogRef.afterClosed().subscribe(() => {
            this.clickoutHandler = null;
          });
        });
      }
    
      closeDialogFromClickout(event: MouseEvent) {
        const matDialogContainerEl = this.dialogRef.componentInstance.hostElement.nativeElement.parentElement;
        const rect = matDialogContainerEl.getBoundingClientRect()
        if(event.clientX <= rect.left || event.clientX >= rect.right || 
            event.clientY <= rect.top || event.clientY >= rect.bottom) {
          this.dialogRef.close();
        }
      }
    }
    
    @Component({
      selector: 'dialog-overview-example-dialog',
      templateUrl: 'dialog-overview-example-dialog.html',
    })
    export class DialogOverviewExampleDialog {
    
      constructor(
        public hostElement: ElementRef,
        public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
        @Inject(MAT_DIALOG_DATA) public data: DialogData) {
      }
    
      onNoClick(): void {
        this.dialogRef.close();
      }
    }
    

    【讨论】:

      【解决方案3】:

      有很多方法可以实现这一点。一种是听窗口点击。 Stackblitz

      export class DialogOverviewExampleDialog {
      
        private inited;
      
        constructor(
          public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
          @Inject(MAT_DIALOG_DATA) public data: DialogData) { }
      
        ngOnInit() {
            this.dialogRef.afterOpened().subscribe(() => {
              this.inited = true;
            })
        }
      
        @HostListener('window:click')
        onNoClick(): void {
          if (this.inited) {
              this.dialogRef.close();
          }
        }
      
      }
      

      但我建议您编辑背景的 css,使其保持不可见但功能保留。

      .cdk-overlay-dark-backdrop {
          background: transparent;
      }
      

      【讨论】:

      • 如果我这样做,我必须在按钮上单击两次以关闭背景一次以单击按钮stackblitz.com/edit/angular-tkg6v6-sxgzbz?file=app/…
      • 如果背景是透明的,则表明其他元素是功能性的,因此保持标准功能性将是相当破坏的行为。
      猜你喜欢
      • 2023-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-29
      • 1970-01-01
      • 2014-11-06
      • 2018-09-12
      • 2023-02-23
      相关资源
      最近更新 更多