Angularにng-bootstrapをインストールする方法と使い方
ng-bootstrap をインストールする方法です。
npm install --save @ng-bootstrap/ng-bootstrap
ng-bootstrap は、bootstrap に依存するので、bootstrap をインストールします。
npm install bootstrap --save
app.module.tsファイルを修正します。
app.module.ts
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';// この行を追加 imports: [ BrowserModule, NgbModule.forRoot() // この行を追加 ],
angular.jsonファイルを修正します。
angular.json
"styles": [ "node_modules/bootstrap/dist/css/bootstrap.css",// この行を追加 "src/styles.css" ],
これで、ng-bootstrapが使えるようになります。
ng-bootstrap を使ったタブを作成してみます。
(tabChange)イベントバインディングを使用する
(tabChange)というイベントバインディングが使用できます。
ngb-tabsetタグに設定します。
import { Component } from '@angular/core'; import { NgbTabChangeEvent } from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'app-root', template: ` <ngb-tabset (tabChange)="onChange($event)"> <ngb-tab title="あ"> <ng-template ngbTabContent>あああ</ng-template> </ngb-tab> <ngb-tab title="か"> </ngb-tab> <ngb-tab title="さ"> </ngb-tab> </ngb-tabset> `, styleUrls: ['./app.component.css'] }) export class AppComponent { onChange(e){ console.log(e.activeId); // activeIdというプロパティがある console.log(e.nextId); // nextIdというプロパティがある } }
ngbTabContentがないと表示されません。以下、実行例です。
ちなみに、ngb-tabタグにイベントバインディング(click)や(select)を指定してみましたが実行されませんでした。
<ngb-tabset (tabChange)="onChange($event)"> <ngb-tab title="あ" (click)="onClick()"> <!-- (click)は実行されない --> <ng-template ngbTabContent>あああ</ng-template> </ngb-tab> <ngb-tab title="か"> かかか </ngb-tab> <ngb-tab title="さ"> さささ </ngb-tab> </ngb-tabset>
アクティブなngb-tabを調べる
どのngb-tabがアクティブかを調べるにはngb-tabにid属性を指定します。これは必ず指定しておいた方が良いです。でないとactiveIdプロパティやnextIdプロパティで取得できるidは適当になってしまいます。
以下、例です。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <ngb-tabset (tabChange)="onChange($event)"> <ngb-tab title="あ" id="aaa"> <ng-template ngbTabContent>あああ</ng-template> </ngb-tab> <ngb-tab title="か" id="bbb"> </ngb-tab> <ngb-tab title="さ" id="ccc"> </ngb-tab> </ngb-tabset> `, styleUrls: ['./app.component.css'] }) export class AppComponent { constructor() { } onChange(e) { console.log(e.nextId); } }
nextIdプロパティから、タブを変更したタイミングで現在アクティブなタブのid属性が取得できます。
ボタンでタブをアクティブにする
ngb-tabsetタグに#xxx=ngbTabset
とつけることでタブを操作できます。
例えばボタンをクリックすると一番右のタブをアクティブにする、などです。
実装は以下の通りid属性も必要になります。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <ngb-tabset #aiueo="ngbTabset"> <ngb-tab title="あ" id="aaa"> </ngb-tab> <ngb-tab title="か" id="bbb"> </ngb-tab> <ngb-tab title="さ" id="ccc"> </ngb-tab> </ngb-tabset><br> <button (click)="aiueo.select('ccc')">ボタン</button> `, styleUrls: ['./app.component.css'] }) export class AppComponent { constructor() {} }
xxx.select(id属性値)
上記のようにすることでアクティブなタブを指定することができます。
タブ内のフォーム部品の値を保持する
各タブにフォーム部品がある場合、タブを遷移しても値を保持していたいです。が、デフォルトではタブを遷移すると値が消えてしまうようです。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <ngb-tabset #aiueo="ngbTabset"> <ngb-tab title="あ" id="aaa"> <ng-template ngbTabContent> <input type="text"> </ng-template> </ngb-tab> <ngb-tab title="か" id="bbb"> <ng-template ngbTabContent> <input type="checkbox"> </ng-template> </ngb-tab> <ngb-tab title="さ" id="ccc"> </ngb-tab> </ngb-tabset> `, styleUrls: ['./app.component.css'] }) export class AppComponent { constructor() {} }
これを実行してみます。タブを遷移して元のタブに戻るとフォーム部品の入力値は保持されないことが確認できます。
これを保持するように属性で変更することができます。
<ngb-tabset [destroyOnHide]="false">
このように属性を追加します。省略した場合、デフォルトはtrueのようです。
タブ遷移してもフォーム部品の入力値が保持されることが確認できます。
ちなみにdestroyOnHideをtrueにすると、タブ内のコンポーネントは初期表示時にインスタンス生成されるようになります。falseの場合、タブを変えたタイミングでタブ内のコンポーネントが毎回生成される動きになります。
タブを非表示にする
タブを非表示にするには*ngIf=false
とすれば非表示にすることができます。
実際はboolean型の変数を指定して、表示非表示を切り替えるという事になると思います。
タブのナビゲーションを変更する
タブのナビゲーションはデフォルトはtabs
です。もう一つタイプがあるようで、pills
と指定することでナビゲーションを変更することができます。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <ngb-tabset type="pills"> <ngb-tab title="あ"> </ngb-tab> <ngb-tab title="か"> </ngb-tab> <ngb-tab title="さ" id="ccc"> </ngb-tab> </ngb-tabset><br> `, styleUrls: ['./app.component.css'] }) export class AppComponent { constructor() {} }
以下のようにデザインが変わります。
NgbModalでモーダルウィンドウを開く
NgbModalをインポートして、モーダルウィンドウ(これもコンポーネント)を作成してみます。
呼び出す画面でボタンを作成し、そのボタンをクリックすればモーダルウィンドウが開くようにします。モーダルウィンドウもコンポーネントとして作成しておく必要があります。
ここでは
ng generate component modal1
としておきます。
これで、app.component.tsにモーダルを呼び出すボタンを実装します。
import { Component } from '@angular/core'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { Modal1Component } from './modal1/modal1.component';// モーダルコンポーネント @Component({ selector: 'app-root', template: ` <div style="text-align:center"> <button type='button' (click)='onClick()'>モーダルボタン</button> </div> `, styleUrls: ['./app.component.css'] }) export class AppComponent { constructor(private modal: NgbModal) {} onClick() { const modal = this.modal.open(Modal1Component); } }
No component factory found for Modal1Component. Did you add it to @NgModule.entryComponents?
こんなエラーがでました。モーダルとするコンポーネントは@NgModuleのentryComponentsに追加してあげないといけないようです。
ということで、app.module.jsを修正します。
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; import { AppComponent } from './app.component'; import { Modal1Component } from './modal1/modal1.component'; @NgModule({ declarations: [ AppComponent, Modal1Component ], imports: [ BrowserModule, NgbModule.forRoot() ], entryComponents: [Modal1Component], // この行を追加 providers: [], bootstrap: [AppComponent] }) export class AppModule { }
これでng serve --o
します。
モーダルが表示されるようになりました。
呼び出し元からモーダルに値を渡す
モーダル画面を作成したら、パラメータのやり取りを行いたいですね。呼び出し元から値を渡したり、呼び出し元に値を戻したりといったことを実装してみます。
まずは呼び出し元画面からモーダル画面に値を渡す方法です。
- 呼び出し元画面 → モーダル画面
呼び出し元画面から呼び出し先画面に値を渡すには@Inputを使用します。これはモーダルに限らず親コンポーネントから子コンポーネントにデータを渡すときには@Inputを使用します。
まず呼び出し元画面からパラメータを渡すために修正します。ここではaとbという名前でパラメータを2つ渡しています。
import { Component } from '@angular/core'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { Modal1Component } from './modal1/modal1.component';// モーダルコンポーネント @Component({ selector: 'app-root', template: ` <div style="text-align:center"> <button type='button' (click)='onClick()'>モーダルボタン</button> </div> `, styleUrls: ['./app.component.css'] }) export class AppComponent { constructor(private modal: NgbModal) {} onClick() { const modal = this.modal.open(Modal1Component); modal.componentInstance.a = 'aパラメータ';// パラメータ名は任意(ここではa) modal.componentInstance.b = 'bパラメータ';// パラメータ名は任意(ここではb) } }
パラメータを受け取るためにモーダル画面のコンポーネント(ここではmodal1.component.ts)も修正する必要があります。
modal1.component.ts
import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'app-modal1', template: ` <div style="text-align:center"> <p>{{a}}-{{b}}</p> <!-- とりあえず表示する --> </div> `, styleUrls: ['./modal1.component.css'] }) export class Modal1Component implements OnInit { constructor() { } @Input() a; // パラメータを用意するだけ @Input() b; // パラメータを用意するだけ ngOnInit() { } }
これでng serve --o
します。
モーダル画面にパラメータが渡っていることが確認できました。
次にモーダル画面から呼び出し元画面にパラメータ(戻り値)を渡したいと思います。
- モーダル画面 → 呼び出し元画面
モーダル画面のほうでNgbActiveModalをインポートし、closeメソッドがあるのでそのメソッドでモーダル画面を閉じます。closeメソッドの引数が戻り値になります。
modal1.component.ts
import { Component, OnInit, Input } from '@angular/core'; import {NgbActiveModal} from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'app-modal1', template: ` <button type="button" (click)="activeModal.close('ボタン押下')">閉じる</button> `, styleUrls: ['./modal1.component.css'] }) export class Modal1Component implements OnInit { constructor(public activeModal: NgbActiveModal) { } ngOnInit() { } }
呼び出し元画面で戻り値を表示します。
import { Component } from '@angular/core'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { Modal1Component } from './modal1/modal1.component';// モーダルコンポーネント @Component({ selector: 'app-root', template: ` <div style="text-align:center"> <button type='button' (click)='onClick()'>モーダルボタン</button><br> <p>{{ret}}</p> </div> `, styleUrls: ['./app.component.css'] }) export class AppComponent { ret: string; constructor(private modal: NgbModal) {} onClick() { const modal = this.modal.open(Modal1Component); modal.result.then((result) => { this.ret = result;// 戻り値 }); } }
resultがPromiseになるので、thenメソッドの引数が戻り値となります。
戻り値が呼び出し元画面に表示されるのが確認できます。
モーダルのデザイン
モーダルのデザインがいけてないので、デザインをモーダルっぽくしてみます。
大きくヘッダとボディとフッタに分けることができます。modal-header,modal-body,modal-footerクラスが用意されています。
modal1.component.ts
import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'app-modal1', template: ` <div class="modal-header"> <h6>ヘッダ部</h6> </div> <div class="modal-body"> <p>ボディ部</p> </div> <div class="modal-footer"> <h6>フッタ部</h6> </div> `, styleUrls: ['./modal1.component.css'] }) export class Modal1Component implements OnInit { constructor() { } ngOnInit() { } }
以下のように表示されるようになります。
とりあえずモーダルぽく?なりました。さらにヘッダ部はウィンドウぽく×ボタンでとじれるように×ボタンを表示してみます。
フッタ部はデフォルトで右寄せのようなので、OKやキャンセルボタンを配置するとモーダルぽくなるように思います。
modal1.component.ts
import { Component, OnInit, Input } from '@angular/core'; import {NgbActiveModal} from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'app-modal1', template: ` <div class="modal-header"> <h6>ヘッダ部</h6> <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('×ボタンクリック')"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p>ボディ部</p> </div> <div class="modal-footer"> <button (click)="activeModal.close('戻り値')">OK</button> </div> `, styleUrls: ['./modal1.component.css'] }) export class Modal1Component implements OnInit { constructor(public activeModal: NgbActiveModal) { } ngOnInit() { } }
×ボタンではdismissメソッドを使用します。×ボタンは特殊文字でとりあえず表示しています。
モーダルのクローズがどうやってクローズされたかを判断する
モーダルはdismisssメソッドでもcloseメソッドでも、モーダル以外の場所をクリックしても閉じられます。ついでにEscを押しても閉じられます。
ng-bootstrapでは、どの操作でとじられたかを判断することができます。
app.component.ts
import { Component } from '@angular/core'; import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap'; import { Modal1Component } from './modal1/modal1.component';// モーダルコンポーネント @Component({ selector: 'app-root', template: ` <div style="text-align:center"> <button type='button' (click)='onClick()'>モーダルボタン</button><br> <p>{{ret}}</p> </div> `, styleUrls: ['./app.component.css'] }) export class AppComponent { ret: string; constructor(private modal: NgbModal) {} onClick() { const modal = this.modal.open(Modal1Component); modal.result.then((result) => { this.ret = result;// 戻り値 }, (reason) => { if (reason === ModalDismissReasons.ESC) { this.ret = 'エスケープ'; } else if (reason === ModalDismissReasons.BACKDROP_CLICK) { this.ret = '背景をクリック'; } else { this.ret = 'それ以外';// dismissの場合このロジックを通る } return this.ret; }); } }
result.thenの第二引数にアロー関数を指定します。また、ModalDismissReasonsをインポートします。
これでエスケープなのかcloseメソッドなのかdismissメソッドなのか背景をクリックしたのかがわかります。
以下実行例です。
ツールチップを表示する
ng-bootstrapでツールチップを表示します。<div>タグや<button>タグにツールチップを指定することができます。上下左右の表示することができ、placement属性で指定します。
app.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: `<br><br><br> <div style="text-align:center"> <p class="btn btn-outline-secondary" [ngbTooltip]="aaa" placement="top"> この文字の上にツールチップを </p> <ng-template #aaa> tool tip top! </ng-template> <hr> <p class="btn btn-outline-secondary" [ngbTooltip]="bbb" placement="left"> この文字の左にツールチップを </p> <ng-template #bbb> tool tip left! </ng-template> <hr> <p class="btn btn-outline-secondary" [ngbTooltip]="ccc" placement="right"> この文字の右にツールチップを </p> <ng-template #ccc> tool tip right! </ng-template> <hr> <p class="btn btn-outline-secondary" [ngbTooltip]="ddd" placement="bottom"> この文字の下にツールチップを </p> <ng-template #ddd> tool tip right! </ng-template> </div> `, styleUrls: ['./app.component.css'] }) export class AppComponent { constructor() {} }
これでng serve
すると以下のように実行されます。
参考サイト:Angularにngx-bootstrapをインストールする方法

KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^
コメント