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

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

» 2017年12月05日 05時00分 公開
[山田祥寛]
「Angular TIPS」のインデックス

連載目次

現在では、Web標準技術を利用したアプリ開発が広く普及し、そのためのフレームワークも多数存在しています。その中でも主流のフレームワークの1つである「Angular」を活用し、そのための知識を備えることには大きな意味があります。本連載は、Angularユーザーに向けて、その使いこなしTIPSを紹介するものです。なお、本連載は「Build Insider」で公開していた連載「Angular Tips」を同サイトおよび筆者の了解を得たうえで、本フォーラムに移行したものです。記事はBuild Insiderで公開した状態のまま移行しているため、用語統一などの基準が@ITの通常の記事とは異なる場合があります。


【対応バージョン】

 Angular 5以降。v5時点で執筆しました。


【注意】Angular 4以前からの本TIPS読者へ

 今回からAngular 5ベースで執筆していきます。

 2017年11月1日以降、QuickStartが非推奨となりました。このため、2017年11月27日以前のAngular TIPSはQuickStartベースとなっていましたが、2017年12月5日以降、全てのAngular TIPSをAngular CLI前提に変更しました。

 QuickStartベースではmy-appという名前のセレクターが使われていましたが、CLIではapp-rootという名前のセレクターが自動生成されるため、全てのAngular TIPSのサンプルコードの「my-app」を「app-root」に書き換えました。

 読者がこれまで作成したきたQuickStartベースのアプリについても、推奨されているAngular CLIで実行する際には、全てのソースファイルにおける<my-app>要素は<app-root>要素に、selector: 'my-app'はselector: 'app-root'という記載に変更してください。これを行わない場合、TIPSのサンプルコードのセレクター名と手元のソースコードのセレクター名に食い違いが生じてエラーとなる可能性があるので注意が必要です。

 逆に、QuickStartベースで実行する必要がある際には、全てのソースファイルにおける<app-root>要素は<my-app>要素に、selector: 'app-root'はselector: 'my-app'に変更してください。繰り返しになりますが、QuickStartは非推奨となっており、本TIPSとしても、今後はAngular CLIに切り替えることを推奨します。


 ngPluralディレクティブは、i18nPluralパイプのディレクティブ版。与えられた式の値が単数/複数(またはいくつか)によって、出力を切り替えるためのディレクティブです。

 例えば以下は、メールボックスなどのアプリを想定したものです。新着メールの件数に応じて、以下のようなメッセージを表示させるものとします。

件数 メッセージ
0 新着メールはありません。
1 新着メールがあります。
2以上 ●○件の新着メールがあります。
新着メールの件数によってメッセージを変化

 このようなメッセージの差し替えを、ngPluralディレクティブで実装しているのが、以下のコードです。

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
  <div [ngPlural]="mails.length">
    <ng-template ngPluralCase="=0">新着メールはありません。
    </ng-template>
    <ng-template ngPluralCase="=1">新着メールがあります。
    </ng-template>
    <ng-template ngPluralCase="other">
      {{mails.length}}件の新着メールがあります。
    </ng-template>
  </div>
  `
})
export class AppComponent {
  // 新着メール情報
  mails = [
    { name: '山田太郎', body: 'こんにちは。今年は暑いねー。' },
    { name: '鈴木久美子', body: 'お久しぶりです。元気にしてますか?' },
    { name: '佐藤雄二', body: '今度の日曜日、ランチしに行きませんか。' },
    { name: '山口夕夏', body: 'お誕生日おめでとう!' },
    { name: '田中仁', body: 'いつもお世話になっております。明日はよろしくお願い致します。' }
  ];
}

変数の値によってメッセージを切り替えるためのコード(app.component.ts)

新着メールの件数(mails.length)によってメッセージが変化(1)
新着メールの件数(mails.length)によってメッセージが変化(2)
新着メールの件数(mails.length)によってメッセージが変化(3) 新着メールの件数(mails.length)によってメッセージが変化*1

*1 メッセージの変化を確認するには、mailsプロパティ(配列)に含まれる要素の個数を変えてください。


 ngPluralディレクティブの構文は、以下の通りです。

[構文]ngPluralディレクティブ

<element [ngPlural]="value">
&nbsp: <ng-template ngPluralCase="num">message</ng-template>
&nbsp: ...
</element>

  • element: 任意の要素
  • value: 任意の式
  • num: 引数valueに対応する値
  • message: 件数に応じたメッセージ

 式(引数value)の値が、引数numに一致する場合に、<ng-template>要素配下のメッセージを表示します。引数numの「=0」「=1」は、「0、1に等しい場合」を意味します。ここでは利用していませんが、「=2」「=3」……で2以上の値を表すことも可能です。また、「いずれの値にも合致しない場合」を表すには、「other」としてください。

 i18nPluralパイプと異なり、メッセージはテンプレートの一部なので、{{...}}構文を使えば、メッセージには任意の値を埋め込むことも可能です(パイプでは、基本的に#で元の値を埋め込めるだけです)。

 その性質上、動的にメッセージを組み立てる用途、そもそものメッセージ量が多いような状況では、i18nPluralパイプよりもngPluralディレクティブを利用すべきです。一方、メッセージをテンプレートから切り離したい(=コンポーネント側で管理したい)という場合には、メッセージ定義を連想配列で表現できるi18nPluralパイプの方が便利でしょう。

処理対象:ディレクティブ(Directive) カテゴリ:基本
API:NgPlural(*ngFor) カテゴリ:@angular > common > DIRECTIVE(ディレクティブ)


「Angular TIPS」のインデックス

Angular TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。