Angular TIPS

Angular TIPS

条件式に応じて要素を表示/非表示にするには?(ngIf)

2017年11月20日

与えられた条件式に基づき要素の表示/非表示を切り替えるngIfディレクティブの基本的な使い方を説明。また、ngIfディレクティブによる表示/非表示の挙動の特性と注意点も示す。

  • このエントリーをはてなブックマークに追加

【対応バージョン】 Angular 4以降。v4時点で執筆しました。

 ngIfディレクティブは、いわゆるJavaScriptのif命令に相当するディレクティブです。指定された条件式がtrueである場合にだけ、現在の要素を表示します。

 まずは具体的な例を見てみましょう。以下は、チェックボックスのオン/オフに応じて、<div id="panel">要素の表示/非表示を切り替える例です*1

TypeScript
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 />
      <!--1showプロパティのtrue/falseに応じてパネルを表示/非表示-->
      <div id="panel" *ngIf="show"
        style="border:solid 1px #000; width: 400px; padding: 10px;">
      あいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそあいうえおかきくけこさしすせそ
      </div>
    </form>
  `,
})
export class AppComponent  {
  show = false;
}
パネルの表示/非表示を切り替えるためのコード(app.component.ts)
[表示]チェックボックスにチェックを入れると……

[表示]チェックボックスにチェックを入れると……

チェックボックスのオン/オフに応じてパネルを表示/非表示
チェックボックスのオン/オフに応じてパネルを表示/非表示

 ngIfディレクティブには、truefalseで評価できる式を指定します。この例であれば、コンポーネントのshowプロパティをngIfディレクティブの条件式として<div id="panel">要素に関連付けており(1)、さらにshowプロパティはチェックボックスにも双方向バインディングで関連付けられています(2)(=チェックボックスのオン/オフの状態がそのままshowプロパティに設定される)ので、結果、チェックボックスのオン/オフによって<div id="panel">要素が表示/非表示されることになります。

ngIfディレクティブの内部的な挙動

 チェックボックスをオン/オフにしたときの文書ツリーの変化を、ブラウザー付属の開発者ツールでも確認しておきましょう。

「ngIfディレクティブ」による文書ツリーの変化を確認(上:パネル非表示時、下:パネル表示時)

 ngIfディレクティブによる表示/非表示の切り替えは、displayスタイルプロパティによる制御ではなく、文書ツリーそのものの操作であることが分かります。条件式がfalseである時、Angularは該当する要素を破棄し、trueとなったタイミングで再生成するのです。

 一般的には、文書ツリーに存在する要素は表示/非表示の状態にかかわらず、リソースを消費します。具体的には、Angularは不可視の要素に対してもバインド式の変化を監視します。言うまでもなく、不要なリソースの消費は望ましい状態ではありませんので、ngIfディレクティブでは要素そのものを破棄するという選択肢を採っているのです。

 もっとも、例外はあります。というのも、要素(コンポーネント)によっては、初期化に高いオーバーヘッドを要する場合があります。そのような要素を頻繁に表示/非表示すべきではありません。ngIfディレクティブでは、その性質上、表示/非表示の都度、初期化処理が発生するからです。

 そのような状況を避けるには、ngIfディレクティブではなく、スタイルバインディングでhiddenスタイルを設定してください。

HTML
<div id="panel" [hidden]="!show"
  style="border:solid 1px #000; width: 400px; padding: 10px;">
あいうえおかきくけこさしすせそ...
</div>
スタイルバインディングを利用した例(app.component.ts)
「スタイルバインディングでhiddenスタイル設定」による文書ツリーの変化を確認(パネル非表示時)
「スタイルバインディングでhiddenスタイル設定」による文書ツリーの変化を確認(パネル表示時)
「スタイルバインディングでhiddenスタイル設定」による文書ツリーの変化を確認(上:パネル非表示時、下:パネル表示時)

 スタイルバインディングを利用した状態でパネルの表示/非表示を切り替えた場合、今度は<div>要素が文書ツリーから破棄されないことが確認できます。

[Note]

 displayスタイルプロパティを利用して、以下のように書き換えてもほぼ同じ意味です。

HTML
<div id="panel" [style.display]="show ? 'block': 'none'"
  style="border:solid 1px #000; width: 400px; padding: 10px;">
あいうえおかきくけこさしすせそ...
</div>
displayスタイルプロパティを利用した例
処理対象:構造ディレクティブ(Structural directives) カテゴリ:基本
処理対象:テンプレート構文(Template Syntax) カテゴリ:基本
処理対象:NgIf カテゴリ:テンプレート構文(Template Syntax) > ビルトイン構造ディレクティブ(Built-in structural directives)
API:NgIf(*ngIf) カテゴリ:@angular > common > DIRECTIVE(ディレクティブ)

※以下では、本稿の前後を合わせて5回分(第28回~第32回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

28. 配列の内容を順に出力するには?(ngFor)

配列の内容を順に出力できるngForディレクティブ(=ngForOfディレクティブ)の基本的な使い方を説明。また、ngForディレクティブで利用できる特殊変数についてまとめる。

29. 複数の要素を繰り返し出力するには?(ngFor)

配列の内容を順に出力できるngForディレクティブ(=ngForOfディレクティブ)と、ダミーのコンテナー要素(<ng-container>)を使うことで、複数の要素群をまとめて繰り返し出力する方法を説明する。

30. 【現在、表示中】≫ 条件式に応じて要素を表示/非表示にするには?(ngIf)

与えられた条件式に基づき要素の表示/非表示を切り替えるngIfディレクティブの基本的な使い方を説明。また、ngIfディレクティブによる表示/非表示の挙動の特性と注意点も示す。

31. 条件式の真偽に応じて出力を切り替えるには?(ngIf/else)

与えられた条件式に基づき要素の表示/非表示を切り替えるngIfディレクティブで用いる、「さもなければ」を意味するelse句と、テンプレートとして別出しするためのthen句の、基本的な使い方を説明する。

32. 数値(単数/複数)によって表示を切り替えるには?(ngPlural)

Angularで数値によってテキスト表示内容を切り替えるための、ngPluralディレクティブの基本的な使い方を説明する。

サイトからのお知らせ

Twitterでつぶやこう!