Désactivez le clic en dehors de la zone de dialogue du matériau angulaire pour fermer la boîte de dialogue (avec Angular Version 4.0+)

102

Je travaille actuellement sur la page de réinitialisation de mot de passe d'un projet Angular 4. Nous utilisons un matériau angulaire pour créer la boîte de dialogue, cependant, lorsque le client clique hors de la boîte de dialogue, elle se ferme automatiquement. Existe-t-il un moyen d'éviter la fermeture de la boîte de dialogue jusqu'à ce que notre côté code appelle la fonction "fermer"? Ou comment créer un modal non fermable ?

Terry Zhang
la source

Réponses:

266

Il y a deux manières de procéder.

  1. Dans la méthode qui ouvre la boîte de dialogue, passez l'option de configuration suivante en disableClosetant que deuxième paramètre MatDialog#open()et définissez-la sur true:

    export class AppComponent {
      constructor(private dialog: MatDialog){}
      openDialog() {
        this.dialog.open(DialogComponent, { disableClose: true });
      }
    }
  2. Vous pouvez également le faire dans le composant de dialogue lui-même.

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

Voici ce que vous recherchez:

Propriété <code> disableClose </code> dans material.angular.io

Et voici une démo de Stackblitz


Autres cas d'utilisation

Voici quelques autres cas d'utilisation et extraits de code expliquant comment les implémenter.

Autoriser escà fermer la boîte de dialogue mais interdire de cliquer sur le fond pour fermer la boîte de dialogue

Comme l'a dit @MarcBrazeau dans le commentaire ci-dessous ma réponse, vous pouvez autoriser la escclé à fermer le modal mais toujours interdire de cliquer en dehors du modal. Utilisez ce code sur votre composant de dialogue:

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();
  }

}

Empêcher escde fermer la boîte de dialogue mais autoriser le clic sur le fond pour fermer

PS C'est une réponse qui provient de cette réponse , où la démo était basée sur cette réponse.

Pour empêcher la escclé de fermer la boîte de dialogue mais permettre de cliquer sur le fond pour fermer, j'ai adapté la réponse de Marc, ainsi que MatDialogRef#backdropClickpour écouter les événements de clic sur le fond.

Initialement, la boîte de dialogue aura l'option de configuration disableClosedéfinie comme true. Cela garantit que le fait d' escappuyer sur une touche, ainsi que de cliquer sur le fond ne provoquera pas la fermeture de la boîte de dialogue.

Ensuite, abonnez-vous à la MatDialogRef#backdropClickméthode (qui émet lorsque le fond est cliqué et revient en tant que a MouseEvent).

Bref, assez de discussions techniques. Voici le code:

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();
  })

  // ...
}

Vous pouvez également le faire dans le composant de dialogue:

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
la source
5
Je trouve ennuyeux que vous deviez désactiver à la fois "échapper et cliquer à l'extérieur". Pour contourner ça:@HostListener('window:keyup.esc') onKeyUp() { this.dialogRef.close(); }
Marc Brazeau
@MarcBrazeau J'ai ajouté votre commentaire à ma réponse.
Edric
1
Un avertissement pour les personnes utilisant des champs de saisie avec saisie semi-automatique. L'utilisation de HostListener ferme la boîte de dialogue lorsque vous fermez la liste de saisie semi-automatique.
Jompis
Merci pour votre aide
Rafael Moura
1
Vous devrez également gérer la désinscription du backdropClick Observable sinon vous introduirez une fuite de mémoire.
sinistre le
3

Que diriez-vous de jouer avec ces deux propriétés?

disableClose: boolean - Indique si l'utilisateur peut utiliser l'échappement ou cliquer sur l'arrière-plan pour fermer le modal.

hasBackdrop: boolean - Indique si la boîte de dialogue a un arrière-plan.

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

alansiqueira27
la source
définir hasBackdrop sur false supprime le noircissement de la zone en dehors de la boîte de dialogue
Mohit Atray
Travaillé avec Angular 9. «hasBackdrop» ne permet pas à l'utilisateur d'interagir avec d'autres éléments extérieurs. disableClose ne permet pas à l'utilisateur de fermer la boîte de dialogue avec un clic extérieur ou une touche d'échappement.
Naveen Kumar V