NgbModalを使う
最近はionicではなく、Angular4を使った開発を行っています。
Angular4を使って、モーダルウインドウを表示する方法と、モーダルウインドウと元のウインドウのデータ受け渡しについての方法を紹介します
何はともあれAngular Bootstrapを導入
Angular4に特化したBootstrapを使います。
なんとも紛らわしいのですが、Bootstrap4はBootstrap4として存在しています。
Bootstrap4の一部機能を、Angularに特化して使いやすくしたものがBootstrap 4 components, powered by Angularのようです。
(間違ってたらすみません)
インストールはいつものようにnpmで行います。
npm install –save @ng-bootstrap/ng-bootstrap
詳しいインストール方法はGetting Startedを読んでいただければ良いと思います。
1つ注意点として、インストール方法にも書いてありますが
- Angular (requires Angular version 4 or higher, tested with 4.0.3)
- Bootstrap CSS (tested with 4.0.0-alpha.6)
が無いと動きません。
これらはnpmでインストールしてもうまくできなかったので、私はCDNで引っ張ってきてしまいました。
index.html
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>sample</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="icon" type="image/x-icon" href="favicon.ico"> <!-- bootstrap4 --> <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous"> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> </head> <body> <app-root>Loading...</app-root> </body> </html>
10行目付近の処理でBootstrap4.0.0-alpha.6をインストールしています
その他、app.module.tsファイルにも追加していきます。(詳しくは公式ガイドを参照)
NgbModalを導入する
ここから本番です。
Modal用コンポーネントを追加
モーダルウインドウは1つのコンポーネントなので、プロジェクトに1つコンポーネントを追加しておきます。
ターミナルから
ng g component mymodal
と入力して、componentを追加します(mymodalの部分は適時変更して下さい)
Modalを使うためのModule追加
app.module.tsにコンポーネントの情報を追加していきます。
import { NgModule } from '@angular/core'; import { NgbModule} from '@ng-bootstrap/ng-bootstrap'; import { AppComponent } from './app.component'; import { mymodalComponent} from './mymodal/mymodal.component'; @NgModule({ declarations: [ mymodalComponent, ], imports: [ NgbModule.forRoot(), ], entryComponents: [mymodalComponent], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
entryComponentsという項目が見慣れないのですが、追加する必要があるようです。これに気づかず少しハマりました。
モーダルウインドウを呼び出す側の処理
NgbModalについて公式のマニュアルはこちらを参照してください
まずモーダルウインドウを呼び出すがわの処理です
import { Component , Input } from '@angular/core'; import { mymodalComponent} from '../mymodal/mymodal.component'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'app-base', templateUrl: './base.component.html', styleUrls: ['./base.component.css'] }) export class baseComponent { constructor(private modalService: NgbModal,) {} open() { const modalRef = this.modalService.open(mymodalComponent); modalRef.componentInstance.name = 'モーダルに文字を渡しましょう'; modalRef.result.then( result => { console.log(result); } ); } }
templateUrlの方で、適当にボタンでも1つ配置しておきます
<button class="btn btn-lg btn-outline-primary" (click)="open()">Launch demo modal</button>
モーダルウインドウが開く時
ボタンを押すと、openメソッドが実行されます。mymodalComponentを呼び出してモーダルとして表示してくれます。
その際に、モーダルウインドウへパラメータを渡すことができます。サンプルコードでは’モーダルに文字を渡しましょう’ というパラメータを渡しています。
モーダルウインドウが閉じる時
モーダルウインドウの閉じるボタンをクリックして、制御が呼び出し元に戻ってきた際、モーダルウインドウからresultとして値を受け取ることが可能です。
modalRef.result.then以下の処理で受け取ります。受け取った値はサンプルではresultという変数に入ってきます。
モーダルウインドウ本体の作成
mymodal.ts
import { Component ,Input} from '@angular/core'; import { NgbActiveModal} from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'app-mymodal', templateUrl: './mymodal.component.html', styleUrls: ['./mymodal.component.css'] }) export class mymodalComponent { @Input() name; constructor(public activeModal: NgbActiveModal) {} btn(){ console.log("おしたな?"); } }
@Input() name; で呼び出し元からデータを受け取ります。サンプルでは
モーダルに文字を渡しましょう
が入ってきます。
モーダルウインドウのtemplateURL側
<div class="modal-header"> <h4 class="modal-title">Hi there!</h4> <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p>Hello, {{name}}!</p> </div> <button (click)="btn()">hoge</button> <div class="modal-footer"> <button type="button" class="btn btn-secondary" (click)="activeModal.close('Close click')">Close</button> </div>
呼び出し元から受け取った文字を画面に表示しています。
ついでにボタンを2つ配置しています。1つはconsole.logを、1つはモーダルウインドウを閉じます。
activeModal.close()の引数に渡したあたいが、呼び出し元に渡す値になります。