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]を参照してください。