 
AngularJS TIPS
数値(単数/複数)によって表示を切り替えるには?(ng-plurlize)
ng-plurizeディレクティブやngMessageFormatモジュールを使うことで、変数の値によってメッセージ内容を切り替える方法を説明する。
 ng-plurizeディレクティブを利用することで、変数の値(単数/複数いずれであるか、3以上である場合、など)によって、表現を切り替えることができます。例えばメールボックスなどのアプリを想定してみましょう。新着メールの件数に応じて、以下のようなメッセージを表示させるものとします。
| 件数 | メッセージ | 
|---|---|
| 0 | 新着メッセージはありません。 | 
| 1 | ○○さんからのメッセージがあります。 | 
| 2 | ○○さん、○○さんからのメッセージがあります。 | 
| 3 | ○○さん、○○さんとあと1人からメッセージが届いています。 | 
| 4以上 | ○○さん、他●○名からメッセージが届いています。 | 
このような表現の差し替えは、以下のようなコードで実現できます。
| <!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> | 
 
 
- *1 サンプルを実行する際には、スコープ変数mailsに含まれる要素の個数を変化させて、メッセージが変化することを確認してください。
 ng-plurize属性(ディレクティブ)は、以下の属性とセットで利用します(ただし、offset属性は任意です)。
| 属性 | 概要 | 
|---|---|
| count | メッセージ切り替えのための値(件数)を表す変数 | 
| when | 件数(count)に応じたメッセージのセット | 
| offset | 件数(count)から差し引く値 | 
 when属性は「件数: メッセージ」のハッシュ形式で表現します。上記のサンプルでは、
- count属性の値が- 0、- 1、- 2
- offset値+1(=- one)
- それ以上(=other)
のときのメッセージを、それぞれ定義していることになります。メッセージには、{{...}}の形式で式を埋め込める他、{}で「count - offset」値を反映できます。
エクスプレッションによるメッセージの切り替え
 AngularJS 1.4以降では、ngMessageFormatというモジュールが導入され、{{...}}(エクスプレッション)だけでng-plurize属性(ディレクティブ)に相当する表現が可能になりました。以下は、先ほどのリストをngMessageFormatモジュールを使って書き換えたものです。
| <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モジュールは、AngularJSのコア(angular-messages.min.js)とは別ファイルに含まれています。利用に当たっては、angular-message-format.min.jsをインポートした上で、現在のモジュールからngMessageFormatモジュールへの依存関係を宣言してください。
あとは、エクスプレッションで、以下の形式でメッセージを定義するだけです。
[構文]ngMessageFormatモジュールの構文
{{count, plural, offset: off
  : num { message }
  : ...
 }}
- count: 件数を表す式
- off: count属性から差し引く値
- num: 件数
- message: num件のときに表示するメッセージ
 ほとんどng-plurize属性のそれと対応していますので、特筆すべき点はあまりありません。一点のみ、メッセージの中で件数を埋め込む箇所は、ng-plurize属性では{}を使っていましたが、ngMessageFormatモジュールでは#で表します。
処理対象:モジュール カテゴリ:基本
API:ngPlurlize(ng-plurlize) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)
API:ngMessages カテゴリ:モジュール(Modules)
※以下では、本稿の前後を合わせて5回分(第24回~第28回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。







