AngularJSフィルター
フィルターとは?
AngularJSでは{{}}というタグを使って、さまざまな値を表示できる。単に値を表示するだけなら、ほとんどプログラミングとはいえない。しかし値というものは、単に「渡されたものをそのまま表示するだけ」とは限らない。
たとえば、数値を金額として₩記号付きで表示したいとする。この場合、すべての出力部分に₩記号を追加していくのは、そう簡単とはいえない。
このような場合に利用されるのが「フィルター」である。フィルターは、さまざまな値を自動的に操作できる機能である。これは次のように使用する。
{{変数 | フィルター}}
変数の後に|記号を付け、その後にフィルターを指定する。複数のフィルターを同時に使うには、次のように書く。
{{変数 | フィルター1 | フィルター2 | ...}}
このようにいくつでもつなげて使える。
AngularJS自体には一般的なフィルターがいくつか用意されており、いつでも使用できる。また、自分のフィルターをプログラムして使うこともできる。
モジュールとコントローラの作成
フィルターを利用した例を作ってみよう。まずプログラムから作成する。
以下に簡単な例のプログラムを示す。script.jsというファイル名で保存する。
var myapp = angular.module('myapp',[]);
var helo = myapp.controller('HeloController',
function(){
this.count = 0;
this.data = [
{id:0,name:'no data',price:0,get:false,date:1450100000000},
{id:1,name:'Android phone',price:7800,get:true,date:1450400000000},
{id:2,name:'New iPhone',price:549020,get:false,date:1450200000000},
{id:3,name:'windows phone',price:38765,get:true,date:1450300000000}
];
this.getData = function(){
return this.data[this.count].id + ': ' +
this.data[this.count].name + ', ' +
this.data[this.count].price + '.' +
this.data[this.count].date;
};
}
);
今回はHeloControllerクラスに、count、data、getDataというプロパティとメソッドを定義している。dataは非常に簡単なカタログのようなものを表す。ID、名前、価格、所持しているかどうかを示す真偽値、登録日時などの情報がある。登録日時はタイムスタンプの整数値で指定されている。
このdataのデータをテンプレートで表示するときに、フィルターを利用する。
値をフィルタリングする
フィルターを使ってデータを表示してみる。HTMLファイルの例は次のとおりである。
<! DOCTYPE html>
<html>
<head>
<title>AngularJS Sample</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="script.js"></script>
<style>
body { color:gray; }
h1 { font-size:18pt; font-weight:bold; }
span.label { display:inline-block;width:50px; color:red; }
input { width:100px; }
.msg { font-size:14pt; font-weight:bold;color:gray; }
th { color:#eee; background-color:#999; padding: 5px 10px;}
td { color:#333; background-color:#ddd; padding: 5px 10px;}
</style>
</head>
<body ng-app="myapp" ng-init="num=0">
<h1>データ表示</h1>
<div ng-controller="HeloController as ctl">
<table>
<tr><th>ID</th><th>NAME</th><th>PRICE</th><th>GET?</th><th>DATE</th></tr>
<tr ng-repeat="obj in ctl.data">
<td>{{obj.id}}</td>
<td>{{obj.name}}</td>
<td>{{obj.price | currency:'₩'}}</td>
<td>{{obj.get}}</td>
<td>{{obj.date | date:'yyyy-MM-dd'}}</td>
</tr>
</table>
</div>
</body>
</html>
このようにソースコードを再びブラウザに表示してみる。
今回はPRICEとDATE項目にフィルターを設定している。それぞれの出力部分を見てみよう。
PRICE出力
{{obj.price | currency : '₩'}}
obj.priceの後にcurrencyというフィルターを設定している。これは数値を金額としてフォーマットして表示するフィルターである。フィルターによっては必要な値を用意するものがある。このcurrencyもその1つで、₩を指定することでウォン表記に設定できる。出力表示を見ると、₩ 7,800.00のような形式で表示されることを確認できるだろう。
DATE出力
{{obj.date | date : 'yyyy-MM-dd'}}
obj.dateの後にdateというフィルターが設定されている。これはDateオブジェクトの値を特定の形式にフォーマットするフィルターである。ここではyyyy-MM-ddに設定している。これにより、たとえば2015-12-14という形式で日付が表示される。
ところで、date値はタイムスタンプ整数だった。dateフィルターを利用すると、タイムスタンプをもとにDateオブジェクトを生成し、それをもとに指定された形式でフォーマットされたテキストを取得できる。
このようにフィルターを使うと、単純な数値を金額表記にしたり、日付を表示したりできる。
標準フィルター
フィルターは非常に簡単に使えるが、どのようなフィルターが用意されているか分からなければ使えない。ここではAngularJSに標準で提供されているフィルターについて説明する。
currency
数値を金額として表記するためのフィルターである。単にcurrencyだけを指定するとドル表記で表示される。currency : '₩'のようにするとウォンが表示される。
date
Date値を定められた形式の日付テキストに整形するフィルターである。フォーマット名またはパターンを値として指定する。フォーマット名とパターンで使用できるメタ文字は次のとおりである。
フォーマット名
| フォーマット名 | 説明 |
|---|---|
| short, shortTime, shortDate | 短い形式のフォーマットである。 |
| medium, mediumTime, mediumDate | 通常使用される形式のフォーマットである。 |
| longDate, fullDate | 長い形式の日付フォーマットである。 |
パターンのメタ文字
| 文字 | 説明 |
|---|---|
| y | 年を表す。 |
| M | 月を表す。 |
| d | 日を表す。 |
| E | 曜日を表す。 |
| H | 24時間制の時間を表す。 |
| h | 12時間制の時間を表す。 |
| m | 分を表す。 |
| s | 秒を表す。 |
| .sss | ミリ秒を表す。 |
| a | 午前、午後を表す。 |
| z | タイムゾーンを表す。 |
number
数値を特定の桁数で丸めて表示するフィルターである。たとえばnumber : 4とすると、先頭4桁だけを表示し、5桁目を丸める。
json
オブジェクトの値をJSON形式に変換して出力するフィルターである。
uppercase / lowercase
テキストをすべて大文字または小文字に変換するフィルターである。
カスタムフィルター
フィルターは標準で提供されるものだけでなく、ユーザーが自分で作ることもできる。このカスタムフィルターは次のような形で定義する。
コントローラ.filter(名前, 関数);
コントローラのfilterメソッドを使ってフィルターを登録する。引数にはフィルター名と、フィルター処理を実装した関数が必要である。
引数に設定される関数は、おおむね次のような形で定義する。
function(val) {
... 中略 ...
return 値;
}
引数として渡されるものが、フィルターにかけられた元の値である。そしてreturnするものがフィルタリング後の値である。つまり、関数内で引数の値をどのように変換して返すかを考えながらコーディングすれば、フィルターは比較的簡単に作れる。
getItフィルター
では簡単な例を作ってみよう。コントローラに用意されているdataには、購入有無を真偽値で表すget値があった。これをもう少し分かりやすく表示するフィルターを考えてみる。
以下に例を示す。
helo.filter('getIt',
function(){
return function(val) {
return val ? "✔" : "-";
};
}
);
これをscript.jsの末尾に追加する。そしてHTMLファイルでgetを表示している部分である{{obj.get}}を、次のように修正する。
<td>{{obj.get | getIt}}</td>
このようにgetにフィルターを入れると、✔が表示されることを確認できる。ここではvalの値に応じて✔または-のどちらかを返すようになっており、trueなら✔、falseなら-で表示される。
フィルターに値を設定する
フィルターにはcurrencyやdateのように、何らかの値を設定して呼び出すこともできる。ここではその方法を説明する。
これは簡単である。フィルター関数を定義するとき、2番目の引数を指定して値を渡せるようにする。
前に作ったgetItフィルターを修正し、値を渡せるようにしてみよう。以下に簡単な例を示す。
helo.filter('getIt',
function(){
return function(val,opt) {
var t = (opt == null) ? '✔' : opt;
return val ? t : '-';
};
}
);
2番目の引数optの値がnullでないかを確認し、nullでない場合はtrue時にそれを返すように修正した。nullの場合は✔を返す。
そしてHTMLファイルのobj.getを出力している部分を次のように修正する。
<td>{{obj.get | getIt:'●'}}</td>
これで値がtrueなら●、falseなら-として表示されるようになった。getIt : '●'のように用意した値が、そのままtrueの表示になる。別の値にも変更して、表示がうまくいくか確認してみよう。
フィルターは、引数からどのようにreturn値を生成するかが分かれば、意外と簡単に作れる。また、作ったフィルターを利用するのも非常に簡単である。用途に応じて自分だけのフィルターを作れるようになれば、表現力もずっと高まる。