Desative o clique fora da área de diálogo do material angular para fechar a caixa de diálogo (com Angular versão 4.0+)

99

Atualmente, estou trabalhando na página de redefinição de senha de um projeto Angular 4. Estamos usando Angular Material para criar a caixa de diálogo, no entanto, quando o cliente clica fora da caixa de diálogo, ela será fechada automaticamente. Existe uma maneira de evitar que a caixa de diálogo feche até que nosso código chame a função "fechar"? Ou como devo criar um modal que não pode ser fechado ?

Terry Zhang
fonte

Respostas:

263

Existem duas maneiras de fazer isso.

  1. No método que abre a caixa de diálogo, passe a seguinte opção de configuração disableClosecomo o segundo parâmetro MatDialog#open()e defina-a como true:

    export class AppComponent {
      constructor(private dialog: MatDialog){}
      openDialog() {
        this.dialog.open(DialogComponent, { disableClose: true });
      }
    }
  2. Como alternativa, faça isso no próprio componente de diálogo.

    export class DialogComponent {
      constructor(private dialogRef: MatDialogRef<DialogComponent>){
        dialogRef.disableClose = true;
      }
    }

Aqui está o que você está procurando:

Propriedade <code> disableClose </code> em material.angular.io

E aqui está uma demonstração Stackblitz


Outros casos de uso

Aqui estão alguns outros casos de uso e trechos de código de como implementá-los.

Permite escfechar a caixa de diálogo, mas não permite clicar no pano de fundo para fechar a caixa de diálogo

Como @MarcBrazeau disse no comentário abaixo da minha resposta, você pode permitir que a esctecla feche o modal, mas ainda não permite clicar fora do modal. Use este código em seu componente de diálogo:

import { Component, OnInit, HostListener } from '@angular/core';
import { MatDialogRef } from '@angular/material';
@Component({
  selector: 'app-third-dialog',
  templateUrl: './third-dialog.component.html'
})
export class ThirdDialogComponent {
  constructor(private dialogRef: MatDialogRef<ThirdDialogComponent>) {      
}
  @HostListener('window:keyup.esc') onKeyUp() {
    this.dialogRef.close();
  }

}

Impedir escde fechar a caixa de diálogo, mas permitir clicar no pano de fundo para fechar

PS Esta é uma resposta que teve origem nesta resposta , onde a demonstração foi baseada nesta resposta.

Para evitar que a esctecla feche a caixa de diálogo, mas permitir o clique no pano de fundo para fechar, adaptei a resposta de Marc, além de usar MatDialogRef#backdropClickpara ouvir eventos de clique no pano de fundo.

Inicialmente, a caixa de diálogo terá a opção de configuração disableClosedefinida como true. Isso garante que o escpressionamento de tecla, bem como o clique na tela de fundo, não farão com que a caixa de diálogo feche.

Depois, inscreva-se no MatDialogRef#backdropClickmétodo (que é emitido quando a tela de fundo é clicada e retorna como a MouseEvent).

De qualquer forma, chega de conversa técnica. Aqui está o código:

openDialog() {
  let dialogRef = this.dialog.open(DialogComponent, { disableClose: true });
  /*
     Subscribe to events emitted when the backdrop is clicked
     NOTE: Since we won't actually be using the `MouseEvent` event, we'll just use an underscore here
     See https://stackoverflow.com/a/41086381 for more info
  */
  dialogRef.backdropClick().subscribe(() => {
    // Close the dialog
    dialogRef.close();
  })

  // ...
}

Alternativamente, isso pode ser feito no componente de diálogo:

export class DialogComponent {
  constructor(private dialogRef: MatDialogRef<DialogComponent>) {
    dialogRef.disableClose = true;
    /*
      Subscribe to events emitted when the backdrop is clicked
      NOTE: Since we won't actually be using the `MouseEvent` event, we'll just use an underscore here
      See https://stackoverflow.com/a/41086381 for more info
    */
    dialogRef.backdropClick().subscribe(() => {
      // Close the dialog
      dialogRef.close();
    })
  }
}
Edric
fonte
5
Acho irritante que você tenha que desativar "escapar e clicar fora". Para contornar isso:@HostListener('window:keyup.esc') onKeyUp() { this.dialogRef.close(); }
Marc Brazeau
@MarcBrazeau Eu adicionei seu comentário à minha resposta.
Edric,
1
Um aviso para pessoas que usam campos de entrada com preenchimento automático. O uso do HostListener fecha a caixa de diálogo ao fechar a lista de preenchimento automático.
Jompis
Obrigado pela ajuda
Rafael Moura
1
Você também precisaria lidar com o cancelamento da assinatura do pano de fundoClick Observable, caso contrário, ocorrerá um vazamento de memória.
sombrio
3

Que tal brincar com essas duas propriedades?

disableClose: boolean - se o usuário pode usar escape ou clicar na tela de fundo para fechar o modal.

hasBackdrop: boolean - Se a caixa de diálogo tem um fundo.

https://material.angular.io/components/dialog/api

alansiqueira 27
fonte
definir hasBackdrop como false remove o escurecimento da área fora da caixa de diálogo
Mohit Atray
Funcionou com Angular 9. 'hasBackdrop' não permite que o usuário interaja com outros elementos externos. disableClose não permite que o usuário feche a caixa de diálogo com um clique externo ou tecla de escape.
Naveen Kumar V