問題
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することなく親コンポーネントに値やイベントを送ることができるというわけです。