LoginSignup
1
2

More than 1 year has passed since last update.

【Angular Material】Dialogからのイベントを親コンポーネントで検知

Last updated at Posted at 2023-05-09

問題

Angular MaterialのDialogには close メソッドが存在し、これが叩かれたとき呼び出し元コンポーネント(親コンポーネント)ではafterClosedでダイアログからの値を取得することができます。

/** --- 親コンポーネント --- */
@Component({
  selector: '...',
  templateUrl: '...',
})
export class ExampleParentComponent implements OnDestroy {
  subscription = new Subscription();
  constructor(public dialog: MatDialog) {}

  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }

  onClickOpenDialogButton(): void {
    const dialogRef = this.dialog.open(ExampleDialogComponent, {
      data: {...},
    });

    this.subscription.add(
      dialogRef.afterClosed().subscribe(result => {
        /** closeに渡された値を取得可能 */
      });
    );
  }
}

/** --- ダイアログコンポーネント --- */
@Component({
  selector: '...',
  templateUrl: '...',
})
export class ExampleDialogComponent {
  constructor(
    public dialogRef: MatDialogRef<ExampleDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: DialogData,
  ) {}

  onClickCloseButton(): void {
    this.dialogRef.close(/** params */);
  }
}

ではダイアログを閉じずに値を親コンポーネントに渡すにはどうしたらいいのでしょうか?

解決法

EventEmitterを用います。

/** --- 親コンポーネント --- */
@Component({
  selector: '...',
  templateUrl: '...',
})
export class ExampleParentComponent implements OnDestroy {
  subscription = new Subscription();
  constructor(public dialog: MatDialog) {}

  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }

  onClickOpenDialogButton(): void {
    const dialogRef = this.dialog.open(ExampleDialogComponent, {
      data: {...},
    });

    this.subscription.add(
      dialogRef.componentInstance.emitter.subscribe(result => {
        /** emitが走ったときの処理 */
      })
    );

    this.subscription.add(
      dialogRef.afterClosed().subscribe(result => {
        /** closeに渡された値を取得可能 */
      });
    );
  }
}

/** --- ダイアログコンポーネント --- */
@Component({
  selector: '...',
  templateUrl: '...',
})
export class ExampleDialogComponent {
  @Output() emitter = new EventEmitter<T>();

  constructor(
    public dialogRef: MatDialogRef<ExampleDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: DialogData,
  ) {}

  onClickEmitButton(): void {
    this.emitter.emit(/** params */);
  }

  onClickCloseButton(): void {
    this.dialogRef.close(/** params */);
  }
}

MatDialogRefにはcomponentInstanceプロパティが存在し、これを用いることでダイアログコンポーネントにアクセスできます。
また、EventEmitterにはsubscribeが生えており、emitされたときに配信されます。
この二つを組み合わせることで、ダイアログ上からcloseすることなく親コンポーネントに値やイベントを送ることができるというわけです。

参考

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2