Help us understand the problem. What is going on with this article?

[AngularJS] 6. カスタムフィルタ≪改訂≫

More than 3 years have passed since last update.

目次
≪前の記事 5.イベント処理≪改訂≫
≫次の記事 7.ディレクティブ


【改訂】グローバル変数を使用しない記述法に改訂しました。

フィルタ

フィルタ は出力時に文字列を加工するための機能です。テンプレートの {{ ... }} や ng-bind、ng-bind-html ディレクティブ内で使用します。(1. 初めの一歩も参照)

フィルタ使用例
{{price | number}} 円

上記の例では、 price の値をAngularJS標準の numberフィルタで加工しています。具体的には3桁ごとに「,(カンマ)」が入ります。

AngularJSには標準でいくつかのフィルタが用意されていますが、数も種類も少ないため多くの場合独自に作る必要が生じます。このように独自のフィルタを作成する仕組みが カスタムフィルタ です。

フィルタの定義

カスタムフィルタを定義するには、モジュールオブジェクトの filter メソッドを使用します。

フィルタ定義
モジュールオブジェクト.filter(フィルタ名, function(依存サービス, ...) {
    return function(仮引数) {    ← フィルタの処理を行う関数オブジェクト を返す
        〜出力値の加工処理〜

        return 加工済の値;
    }
});

filterメソッドの第1引数には、定義するフィルタ名を渡します。
第2引数には フィルタの処理を行う関数オブジェクト を返すコールバック関数を渡します。

コールバック関数の内部では、フィルタ処理関数を定義して、その関数オブジェクトを返すようにします。
また、コールバック関数でサービスを利用したい(依存サービス)場合は、そのオブジェクトを引数で渡しておきます。

フィルタ処理関数では引数を1つ受け取ります。この引数に フィルタ前の出力値が渡されます。フィルタ関数の内部ではこの仮引数で出力値を参照し、加工を行います。
そして加工済の値を返すようにします。

フィルタ定義の例

フィルタ定義の例(1)
module.filter('nl2br', function($sce) {
    return function(input) {
        if (input) {
            var replaced = input.replace(/(\r\n|\n|\r)/g, '<br>$1')
            return $sce.trustAsHtml(replaced);
        }
        return input;
    }
});

この例では、文字列の改行コードの前に <br>タグを挿入するフィルタ「nl2br」を定義しています。

変数moduleは、あらかじめ生成したモジュールオブジェクトです。

コールバック関数の引数には SCEサービスのオブジェクト $sce を渡しています。出力時にHTMLタグがエスケープされてしまうのを避けるために $sce.trustAsHtml() メソッドが必要になるからです。
このようにフィルタ処理内で依存するサービスオブジェクトを、コールバック関数の引数に渡しておきます。

フィルタ処理関数では、仮引数inputで出力値(加工前)を受け取っています。そして改行コードの前に<br>タグを挿入する置換処理を行い、置換後の値を返すようにしています。

フィルタ定義の例(2)
module.filter('yenNumber', function($filter) {
    return function(input) {
        if (input) {
            var numfilter = $filter('number');
            return numfilter(input) + '';
        }
        return input;
    }
});

この例は、数字を3桁区切りにしたうえで、末尾に「円」を付けるフィルタ「yenNumber」を定義しています。

数字を3桁区切りにするには、AngularJS標準の number フィルタを利用します。このようにAngularJS標準のフィルタを利用する場合は、コールバック関数に $filterオブジェクトを渡します。

フィルタ処理ではまず、仮引数inputで出力値(加工前)を受け取ります。
AngularJS標準のフィルタ関数は、$filter(フィルタ名) とすることで取得できます。ここでは $filter('number')numberフィルタ関数を取得しています。
そして、 numberフィルタで出力値を加工し、末尾に「円」を付加した値を返しています。

サンプルコード

sample06.html
<!DOCTYPE html>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script>
/**
 * アプリケーション モジュール オブジェクトの定義
 */
(function() {
    var module = angular.module("sampleModule", []);
})();

/**
 * フィルタの定義
 */
(function(module) {
    /**
     * nl2brフィルタ
     */
    module.filter('nl2br', function($sce) {
        return function(input) {
            if (input) {
                var replaced = input.replace(/(\r\n|\n|\r)/g, '<br>$1')
                return $sce.trustAsHtml(replaced);
            }
            return input;
        }
    });

    /**
     * yenNumberフィルタ
     */
    module.filter('yenNumber', function($filter) {
        return function(input) {
            if (input) {
                var numfilter = $filter('number');
                return numfilter(input) + '';
            }
            return input;
        }
    });

    return module;
})(angular.module("sampleModule"));

/**
 * コントローラの定義
 */
(function(module) {
    /**
     * SampleController
     */
    module.controller("sampleController", function($scope, $sce, $timeout){
        $scope.message = "このメッセージは\n改行されて表示されていますか?";
        $scope.price   = 1234567;
    });
})(angular.module("sampleModule"));
</script>

<!-- sampleModule テンプレート -->
<div ng-app="sampleModule">
    <!-- sampleController テンプレート -->
    <div ng-controller="sampleController" ng-cloak>
        <p ng-bind-html="message | nl2br"></p>
        <p>{{price | yenNumber}}</p>
    </div>
</div>

目次
≪前の記事 5.イベント処理≪改訂≫
≫次の記事 7.ディレクティブ


Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away