この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
どうも、福岡のmeです。
今回はAngular6環境でモーダルを作成していました。
普段はBootstrapで作ってしまうのですが、HTMLファイルの中に複数のモーダルを埋めるのはあまりスマートではないと思い
ngx-simple-modal
というモジュールを使ってコンポーネント化してみたところ、シンプルに実装できたのでご紹介したいと思います。
やりたかったこと
- シンプルなモーダルの表示
- モーダル内で行う処理をコンポーネント化したい
- ページ内にコンポーネントとして埋め込みたい
- 複数のモーダルをHTMLファイルにつらつらと書きたくない
Outcome
環境
Angular環境は以下の通りです。
Angular CLI: 6.0.8
Node: 8.11.2
OS: darwin x64
Angular: 6.0.7
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.6.8
@angular-devkit/build-angular 0.6.8
@angular-devkit/build-optimizer 0.6.8
@angular-devkit/core 0.6.8
@angular-devkit/schematics 0.6.8
@angular/cdk 6.3.1-825d35c
@angular/cli 6.0.8
@angular/flex-layout 6.0.0-beta.16
@angular/material 6.2.1
@ngtools/webpack 6.0.8
@schematics/angular 0.6.8
@schematics/update 0.6.8
rxjs 6.2.1
typescript 2.7.2
webpack 4.8.3
インストール
npmを使います。
npm install ngx-simple-modal
コンポーネントの作成
modal.component.tsファイルを作成し、HTMLテンプレートとjs処理を書きます。
`modal.component.ts`
import { Component } from '@angular/core';
import { SimpleModalComponent } from 'ngx-simple-modal';
export interface ConfirmModel {
title: string;
message: string;
}
@Component({
selector: 'confirm',
template: `
<div class="modal-content">
<div class="modal-header">
<h4>{{title || 'Confirm'}}</h4>
</div>
<div class="modal-body">
<p>{{message || 'Are you sure?'}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" (click)="confirm()">はい</button>
<button type="button" class="btn btn-outline-danger" (click)="cancel()">いいえ</button>
</div>
</div>
`
})
export class ConfirmComponent extends SimpleModalComponent<ConfirmModel, boolean> implements ConfirmModel {
title: string;
message: string;
constructor() {
super();
}
confirm() {
// on click on confirm button we set dialog result as true,
// ten we can get dialog result from caller code
this.result = true;
this.close();
}
cancel() {
this.result = false;
this.close();
}
}
app.module.ts にngx-simple-modalモジュールと上で作成したコンポーネントをインポートします。
`app.module.ts`
import { NgModule} from '@angular/core';
import { CommonModule } from "@angular/common";
import { BrowserModule } from '@angular/platform-browser';
import { SimpleModalModule } from 'ngx-simple-modal';
import { ConfirmComponent } from './modal.component';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
CommonModule,
BrowserModule,
SimpleModalModule
],
bootstrap: [AppComponent],
entryComponents: [ConfirmComponent]
})
export class AppModule {}
作成したモーダルのコンポーネントをentryComponentsに追加するのも忘れずに。
挿入したいコンポーネントに追加
上で作成したモーダルをコンポーネントに追加し、呼び出す処理を書きます。
`app.component.ts`
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { SimpleModalService } from 'ngx-simple-modal';
import { ConfirmComponent } from './modal.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private SimpleModalService: SimpleModalService) {}
confirmResult = null;
showConfirm() {
this.SimpleModalService.addModal(ConfirmComponent, {
title: '確認',
message: 'どうしますか?'})
.subscribe((isConfirmed) => {
// Get modal result
this.confirmResult = isConfirmed;
});
}
}
あとはHTMLから
showConfirm()
を呼び出すだけです。
`app.component.html`
<div class="row">
<div class="col-sm-4 text-right">
<b>シンプルなモーダル: </b>
</div>
<div class="col-sm-4">
<button class="btn btn-default btn-block" (click)=showConfirm()>確認する</button>
</div>
<div class="col-sm-4" *ngIf="confirmResult != null">
<span>返答: </span>
<b [ngClass]="{'text-danger': !confirmResult, 'text-success': confirmResult}">{{confirmResult ? 'はい': 'いいえ'}}</b>
</div>
</div>
スタイリング
ngx-simple-modalにはデフォルトのcssをつけることが出来ます。
そのまま利用したい場合はangular.json内でcssを定義します。
`angular.json`
"styles": [
"styles.css",
"../node_modules/ngx-simple-modal/styles/simple-modal.css"
],
まとめ
いかがだったでしょうか。モーダルはHTMLとBootstrapを使えば簡単に作成できますが、
ページにhtmlで書いてしまうと数が増えた時にメンテがしづらくなったり、どのモーダルが何の処理をしているのか読み解きづらくなりがちですよね。
今回はコンポーネント化してしまうことで、よりシンプルに書くことができました。
公式のドキュメントにはもっと色々な使い方を紹介しているので、興味がある方はぜひ参考にしてみてください。