AngularJSフィルター

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クラスに、countdatagetDataというプロパティとメソッドを定義している。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>

このようにソースコードを再びブラウザに表示してみる。

今回はPRICEDATE項目にフィルターを設定している。それぞれの出力部分を見てみよう。

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なら-で表示される。

フィルターに値を設定する

フィルターにはcurrencydateのように、何らかの値を設定して呼び出すこともできる。ここではその方法を説明する。

これは簡単である。フィルター関数を定義するとき、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値を生成するかが分かれば、意外と簡単に作れる。また、作ったフィルターを利用するのも非常に簡単である。用途に応じて自分だけのフィルターを作れるようになれば、表現力もずっと高まる。