Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
AngularJS TIPS

AngularJS TIPS

数値(単数/複数)によって表示を切り替えるには?(ng-plurlize)

2015年9月28日

ng-plurizeディレクティブやngMessageFormatモジュールを使うことで、変数の値によってメッセージ内容を切り替える方法を説明する。

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

 ng-plurizeディレクティブを利用することで、変数の値(単数/複数いずれであるか、3以上である場合、など)によって、表現を切り替えることができます。例えばメールボックスなどのアプリを想定してみましょう。新着メールの件数に応じて、以下のようなメッセージを表示させるものとします。

件数メッセージ
0 新着メッセージはありません。
1 ○○さんからのメッセージがあります。
2 ○○さん、○○さんからのメッセージがあります。
3 ○○さん、○○さんとあと1人からメッセージが届いています。
4以上 ○○さん、他●○名からメッセージが届いています。
新着メッセージの件数によって変化するメッセージ

 このような表現の差し替えは、以下のようなコードで実現できます。

HTML
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body ng-controller="MyController">
<div ng-pluralize count="mails.length" offset="2"
  when="{
    '0': '新着メッセージはありません。',
    '1': '{{mails[0].name}}さんからのメッセージがあります。',
    '2': '{{mails[0].name}}さん、{{mails[1].name}}さんからのメッセージがあります。',
    'one': '{{mails[0].name}}さん、{{mails[1].name}}さんとあと1人からメッセージが届いています。',
    'other': '{{mails[0].name}}さん、{{mails[1].name}}さん、他{}名からメッセージが届いています。'
  }">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script>
angular.module('myApp', [])
  .controller('MyController', ['$scope', function($scope) {
    $scope.mails = [
      { name: '山田太郎', body: 'こんにちは。今年は暑いねー。' },
      { name: '鈴木久美子', body: 'お久しぶりです。元気にしてますか?' },
      { name: '佐藤雄二', body: '今度の日曜日、ランチしに行きませんか。' },
      { name: '山口夕夏', body: 'お誕生日おめでとう!' },
      { name: '田中仁', body: 'いつもお世話になっております。明日はよろしくお願い致します。' }
    ];
  }]);
</script>
</body>
</html>
変数の値によって表現を切り替えるためのコード(plurize.html)
メールの件数(mail.length)によってメッセージが変化(1) メールの件数(mail.length)によってメッセージが変化(2)
メールの件数(mail.length)によってメッセージが変化*1
  • *1 サンプルを実行する際には、スコープ変数mailsに含まれる要素の個数を変化させて、メッセージが変化することを確認してください。

 ng-plurize属性(ディレクティブ)は、以下の属性とセットで利用します(ただし、offset属性は任意です)。

属性概要
count メッセージ切り替えのための値(件数)を表す変数
when 件数(count)に応じたメッセージのセット
offset 件数(count)から差し引く値
ng-plurizeディレクティブの属性

 when属性は「件数: メッセージ」のハッシュ形式で表現します。上記のサンプルでは、

  • count属性の値が012
  • offset+1(=one
  • それ以上(=other

のときのメッセージを、それぞれ定義していることになります。メッセージには、{{...}}の形式で式を埋め込める他、{}で「count - offset」値を反映できます。

エクスプレッションによるメッセージの切り替え

 AngularJS 1.4以降では、ngMessageFormatというモジュールが導入され、{{...}}(エクスプレッション)だけでng-plurize属性(ディレクティブ)に相当する表現が可能になりました。以下は、先ほどのリストをngMessageFormatモジュールを使って書き換えたものです。

HTML
<div>{{mails.length, plural, offset:2
 =0 {新着メッセージはありません。}
 =1 {{{mails[0].name}}さんからのメッセージがあります。}
 =2 {{{mails[0].name}}さん、{{mails[1].name}}さんからのメッセージがあります。}
 one {{{mails[0].name}}さん、{{mails[1].name}}さんとあと1人からメッセージが届いています。}
 other{{{mails[0].name}}さん、{{mails[1].name}}さん、他#名が[いいね!]と言っています。}
 }}</div>
……中略……
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-message-format.min.js"></script>
<script>
angular.module('myApp', [ 'ngMessageFormat' ])
 .controller('MyController', ['$scope', function($scope) {
    ……中略……
  }]);
</script>
前述のリストをngMessageFormatモジュールで書き換えたコード(plurize2.html)

 ngMessageFormatモジュールは、AngularJSのコア(angular-messages.min.js)とは別ファイルに含まれています。利用に当たっては、angular-message-format.min.jsをインポートした上で、現在のモジュールからngMessageFormatモジュールへの依存関係を宣言してください。

 あとは、エクスプレッションで、以下の形式でメッセージを定義するだけです。

[構文]ngMessageFormatモジュールの構文

{{count, plural, offset: off
&nbsp: num { message }
&nbsp: ...
}}

  • count: 件数を表す式
  • off: count属性から差し引く値
  • num: 件数
  • message: num件のときに表示するメッセージ

 ほとんどng-plurize属性のそれと対応していますので、特筆すべき点はあまりありません。一点のみ、メッセージの中で件数を埋め込む箇所は、ng-plurize属性では{}を使っていましたが、ngMessageFormatモジュールでは#で表します。

処理対象:フィルタリング カテゴリ:基本
処理対象:モジュール カテゴリ:基本
API:ngPlurlize(ng-plurlize) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)
API:ngMessages カテゴリ:モジュール(Modules)

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

AngularJS TIPS
24. JavaScriptオブジェクトをJSON形式に変換するには?(json)

jsonフィルターを使って、JavaScriptオブジェクトをJSON形式に変換する方法を説明する。

AngularJS TIPS
25. 式の値によって表示を切り替えるには?(ng-switch)

ng-switchディレクティブを使って、与えられた式の値に応じて、表示すべきコンテンツを切り替える方法を説明する。

AngularJS TIPS
26. 【現在、表示中】≫ 数値(単数/複数)によって表示を切り替えるには?(ng-plurlize)

ng-plurizeディレクティブやngMessageFormatモジュールを使うことで、変数の値によってメッセージ内容を切り替える方法を説明する。

AngularJS TIPS
27. 日付/時刻データを整形するには?(date)

dateフィルターを使って、日付/時刻データを任意の書式に変換する方法を説明する。ロケールの指定方法についても解説。

AngularJS TIPS
28. 配列からm~n件目の要素を取り出すには?(limitTo)

limitToフィルターを使って、配列の先頭から指定された件数だけ要素を取り出す方法を説明。応用例としてページング処理を実装する。

サイトからのお知らせ

Twitterでつぶやこう!