角度マテリアルダイアログ領域の外側でのクリックを無効にしてダイアログを閉じる(Angularバージョン4.0以降)


103

私は現在、Angular 4プロジェクトのパスワードリセットページに取り組んでいます。Angular Materialを使用してダイアログを作成していますが、クライアントがダイアログをクリックすると、ダイアログは自動的に閉じます。コード側が「閉じる」関数を呼び出すまでダイアログを閉じないようにする方法はありますか?または、どのようにして閉じることができないモーダルを作成する必要がありますか?

回答:


267

それを行うには2つの方法があります。

  1. ダイアログを開くメソッドでは、以下の設定オプションに渡すdisableClose2番目のパラメータとして、MatDialog#open()及びそれを設定しますtrue

    export class AppComponent {
      constructor(private dialog: MatDialog){}
      openDialog() {
        this.dialog.open(DialogComponent, { disableClose: true });
      }
    }
    
  2. または、ダイアログコンポーネント自体で行います。

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

ここにあなたが探しているものがあります:

material.angular.ioの<code> disableClose </ code>プロパティ

Stackblitzのデモはこちらです


その他の使用例

他の使用例とそれらを実装する方法のコードスニペットを次に示します。

escダイアログを閉じることを許可しますが、ダイアログを閉じるための背景をクリックすることは許可しません

@MarcBrazeauが私の回答の下のコメントで言ったように、escキーがモーダルを閉じることを許可しても、モーダルの外側をクリックすることは許可しないでください。ダイアログコンポーネントでこのコードを使用します。

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

}

防ぐescダイアログを閉じるからではなく近くに背景をクリックすることができ

PSこれは、この回答に基づいた解答です。デモはこの回答に基づいていました。

escキーがダイアログを閉じないようにして、背景をクリックして閉じることができるようにするために、マークの答えを調整MatDialogRef#backdropClickし、背景へのクリックイベントをリッスンするようにしています。

最初に、ダイアログには設定オプションdisableCloseがとして設定されtrueます。これにより、escキーを押すだけでなく、背景をクリックしてもダイアログが閉じなくなります。

その後、MatDialogRef#backdropClickメソッドをサブスクライブします(これは、背景がクリックされたときに発生し、として戻りますMouseEvent)。

とにかく、十分な技術的な話。これがコードです:

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

  // ...
}

あるいは、これはダイアログコンポーネントで行うことができます:

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

5
「エスケープ」と「外部クリック」の両方を無効にしなければならないのは不愉快です。これを回避するには:@HostListener('window:keyup.esc') onKeyUp() { this.dialogRef.close(); }
Marc Brazeau 2017年

@MarcBrazeau私の回答にコメントを追加しました。
エドリック

1
オートコンプリートで入力フィールドを使用している人に対する警告。オートコンプリートリストを閉じると、HostListenerを使用してダイアログが閉じます。
Jompis

ご協力ありがとうございます
Rafael Moura

1
また、backdropClick Observableからのサブスクライブ解除を処理する必要があります。そうしないと、メモリリークが発生します。
厳しい

3

これら2つのプロパティで遊んでみませんか?

disableClose:boolean-ユーザーがエスケープを使用するか、背景をクリックしてモーダルを閉じることができるか。

hasBackdrop:boolean-ダイアログに背景があるかどうか。

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


hasBackdropをfalseに設定すると、ダイアログの外側の領域が黒くなります
Mohit Atray

Angular 9で使用しました。「hasBackdrop」では、ユーザーは他の外部要素と対話できません。disableCloseは、ユーザーが外部クリックまたはエスケープキーでダイアログを閉じることを許可しません。
Naveen Kumar V
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.