Angular ngx-bootstrap Modals を使ったモーダルとのデータのやり取り

Angular4 系で使える ngx-bootstrap というライブラリの ModalModule を使ったサンプル。

共通的に使えるモーダルコンポーネントを作成しておき、モーダルコンポーネントで入力されたデータを呼び出し元の親コンポーネントに渡すサンプルだ。

という動きをさせてみる。

ngx-bootstrap Modals の仕組み上、ちょっと作るのが手間だったのでコードを用意しておく。

目次

モーダルコンポーネント

これが共通的に呼び出される ModalComponent だ。

import { Component, EventEmitter, Input, Output } from '@angular/core';

/** モーダルコンポーネント */
@Component({
  selector: 'app-modal',
  templateUrl: './modal.component.html',
  styleUrls: ['./modal.component.scss']
})
export class ModalComponent {
  /** モーダルディレクティブを保持する */
  @Input()
  modal: any;
  
  /** モーダルが閉じられた時のイベント */
  @Output()
  close: EventEmitter<string> = new EventEmitter<string>();
  
  /** 入力値を保持しておくプロパティ */
  text: string = '';
  
  /** OK ボタン押下時は (close) イベントを発火させつつモーダルを閉じる */
  onOk(): void {
    this.close.emit(this.text);  // 入力されたテキストを渡す
    this.modal.hide();
  }
  
  /** No ボタンや「×」ボタンなど : ただモーダルを閉じるだけ */
  closeModal(): void {
    this.modal.hide();
  }
}

HTML は以下のとおり。

<div class="modal-dialog modal-sm">
  <div class="modal-content">
    <div class="modal-header">
      <h4 class="modal-title pull-left">モーダル</h4>
      <!-- 閉じるボタン : モーダルを閉じる -->
      <button type="button" class="close pull-right" (click)="closeModal()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    </div>
    <div class="modal-body">
      <!-- テキストを入力させる欄 -->
      <input type="text" [(ngModel)]="text">
    </div>
    <div class="modal-footer">
      <div class="text-right">
        <!-- OK ボタンを押すとモーダルを閉じながら入力したテキストを親コンポーネントに送信する -->
        <button type="submit" class="btn btn-success" (click)="onOk()">OK</button>
        <button type="button" class="btn btn-warning" (click)="closeModal()">No</button>
      </div>
    </div>
  </div>
</div>

親コンポーネント

親コンポーネント側には、ModalComponent (app-modal) を囲む要素に ngx-bootstrap Modals のディレクティブを指定しておく。ココで指定したディレクティブを [modal] Input を通じて渡しておくことで、ModalComponent 内でモーダルを操作できるようにしておく。

<p>
  <button type="button" class="btn btn-primary" (click)="staticModal.show()">モーダルを開く</button>
</p>

<p>結果 : {{ result }}</p>

<!-- モーダルコンポーネントを囲む要素に Modal Directive を指定する -->
<div bsModal #staticModal="bs-modal"
     [config]="{backdrop: 'static'}"
     class="modal"
     tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
  <!-- モーダルコンポーネントには Modal Directive を渡しておき、モーダルを閉じた時に親コンポーネント側でイベントを発火させる -->
  <app-modal [modal]="staticModal" (close)="onResult($event)"></app-modal>
</div>

親コンポーネントの実装は以下のとおり。

/** 結果を受け取って表示するプロパティを用意しておく */
result: string = '';

/** モーダルが閉じられた時 (「(close)」イベント時) に発火する。結果テキストを受け取ってプロパティに設定する */
public onResult(text: string) {
  this.result = text;
}