Angularで「条件式」に応じて要素を表示/非表示にするには?(ngIf):Angular TIPS
与えられた条件式に基づき要素の表示/非表示を切り替えるngIfディレクティブの基本的な使い方を説明。また、ngIfディレクティブによる表示/非表示の挙動の特性と注意点も示す。
※現在では、Web標準技術を利用したアプリ開発が広く普及し、そのためのフレームワークも多数存在しています。その中でも主流のフレームワークの1つである「Angular」を活用し、そのための知識を備えることには大きな意味があります。本連載は、Angularユーザーに向けて、その使いこなしTIPSを紹介するものです。なお、本連載は「Build Insider」で公開していた連載「Angular Tips」を同サイトおよび筆者の了解を得たうえで、本フォーラムに移行したものです。記事はBuild Insiderで公開した状態のまま移行しているため、用語統一などの基準が@ITの通常の記事とは異なる場合があります。
【対応バージョン】
Angular 4以降。v4時点で執筆しました。
ngIfディレクティブは、いわゆるJavaScriptのif命令に相当するディレクティブです。指定された条件式がtrueである場合にだけ、現在の要素を表示します。
まずは具体的な例を見てみましょう。以下は、チェックボックスのオン/オフに応じて、<div id="panel">要素の表示/非表示を切り替える例です*1。
*1 ngModelディレクティブを利用する場合には、あらかじめFormsModuleをインポートしておきます。詳しくは別稿「TIPS:フォームの入力値をコンポーネントと同期するには?(双方向バインディング)」も併せて参照してください。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<form>
<label for="switch">表示:</label>
<!--[2]チェックボックスをshowプロパティにひも付け-->
<input id="switch" name="switch" type="checkbox"
[(ngModel)]="show" />
<hr />
<!--[1]showプロパティのtrue/falseに応じてパネルを表示/非表示-->
<div id="panel" *ngIf="show"
style="border:solid 1px #000; width: 400px; padding: 10px;">
あいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそ
</div>
</form>
`,
})
export class AppComponent {
show = false;
}
ngIfディレクティブには、true/falseで評価できる式を指定します。この例であれば、コンポーネントのshowプロパティをngIfディレクティブの条件式として<div id="panel">要素に関連付けており([1])、さらにshowプロパティはチェックボックスにも双方向バインディングで関連付けられています([2])(=チェックボックスのオン/オフの状態がそのままshowプロパティに設定される)ので、結果、チェックボックスのオン/オフによって<div id="panel">要素が表示/非表示されることになります。
ngIfディレクティブの内部的な挙動
チェックボックスをオン/オフにしたときの文書ツリーの変化を、ブラウザー付属の開発者ツールでも確認しておきましょう。
ngIfディレクティブによる表示/非表示の切り替えは、displayスタイルプロパティによる制御ではなく、文書ツリーそのものの操作であることが分かります。条件式がfalseである時、Angularは該当する要素を破棄し、trueとなったタイミングで再生成するのです。
一般的には、文書ツリーに存在する要素は表示/非表示の状態にかかわらず、リソースを消費します。具体的には、Angularは不可視の要素に対してもバインド式の変化を監視します。言うまでもなく、不要なリソースの消費は望ましい状態ではありませんので、ngIfディレクティブでは要素そのものを破棄するという選択肢を採っているのです。
もっとも、例外はあります。というのも、要素(コンポーネント)によっては、初期化に高いオーバーヘッドを要する場合があります。そのような要素を頻繁に表示/非表示すべきではありません。ngIfディレクティブでは、その性質上、表示/非表示の都度、初期化処理が発生するからです。
そのような状況を避けるには、ngIfディレクティブではなく、スタイルバインディングでhiddenスタイルを設定してください。
<div id="panel" [hidden]="!show"
style="border:solid 1px #000; width: 400px; padding: 10px;">
あいうえおかきくけこさしすせそ...
</div>
スタイルバインディングを利用した状態でパネルの表示/非表示を切り替えた場合、今度は<div>要素が文書ツリーから破棄されないことが確認できます。
[Note]
displayスタイルプロパティを利用して、以下のように書き換えてもほぼ同じ意味です。
<div id="panel" [style.display]="show ? 'block': 'none'"
style="border:solid 1px #000; width: 400px; padding: 10px;">
あいうえおかきくけこさしすせそ...
</div>
処理対象:構造ディレクティブ(Structural directives) カテゴリ:基本
処理対象:テンプレート構文(Template Syntax) カテゴリ:基本
処理対象:NgIf カテゴリ:テンプレート構文(Template Syntax) > ビルトイン構造ディレクティブ(Built-in structural directives)
API:NgIf(*ngIf) カテゴリ:@angular > common > DIRECTIVE(ディレクティブ)
Copyright© Digital Advantage Corp. All Rights Reserved.