Angular2でカスタムPipeを定義する

スポンサーリンク

前回の記事で、Angular2のPipeを紹介しましたが、
すでにはじめから用意されているPipeをいくつか紹介しました。

しかし、Angular2では自分でPipeを定義できるんです。
煩雑になりがちな繰り返し処理をすっきりまとめることができるので、地味に重宝してます。

そこで、今回はカスタムパイプの作成方法を紹介します。

カスタムパイプを定義する

数字を入力すると、それに紐付いた文字列を出力するPipeを定義してみましょう。
サーバーのAPIから取得する値は数字だけど、ブラウザでの表示は文字列」といったよくある場面を想定します。

今回は1〜9までの数字から、家族の続柄の文字列を出力してみましょう。

family-type.pipe.ts

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'family_type' })
export class FamilyTypePipe implements PipeTransform {

    transform(value: number): number {
        let type;

        switch (value) {
            case 1:
                type = '本人';
                break;
            case 2:
                type = '夫';
                break;
            case 3:
                type = '妻';
                break;
            case 4:
                type = '父';
                break;
            case 5:
                type = '母';
                break;
            case 6:
                type = '祖母';
                break;
            case 7:
                type = '祖父';
                break;
            case 8:
                type = '子';
                break;
            case 9:
                type = '孫';
                break;
            default:
                type = 'ロボット';
                break;
        }

        return type;
    }

}

始めに、Pipe, PipeTransform をimportします。
読み込むと @Pipe デコレータが使えるようになるので、Pipeであることを宣言します。
引数にはPipeを使用する際の名前を定義します。{ name: 'family_type' } としました。

PipeTransform はインターフェースです。transform メソッドを備えてます。これがPipeに入力された値を変換する処理本体になります。
最後は return で値を返してあげます。

また、Pipeで複数のオプションを受け取りたい場合は、transform メソッドの引数を追加します。

  transform(value: number, age: number) {
    ...
  }

定義したPipeをコンポーネントで使用する

作成したPipeはそのままでは使えません。
コンポーネント側でimport、併せて @Component 内で読み込んだPipeを使用することを明示する必要があります。

var FAMILY = [
    {
        name: 'のび太',
        type: 1
    },
    {
        name: 'のび太のパパ',
        type: 4
    },
    {
        name: 'のび太のママ',
        type: 5
    },
    {
        name: 'ドラえもん',
        type: 10
    }
];
import { Component } from '@angular/core';

import { FamilyTypePipe } from './family-type.pipe';

@Component({
  selector: 'my-family',
  template: </span>
    <span class="o"><</span><span class="nx">ul</span><span class="o">></span>
      <span class="o"><</span><span class="nx">li</span> <span class="o">*</span><span class="nx">ngFor</span><span class="o">=</span><span class="s2">"let family of FAMILY"</span><span class="o">></span>
        <span class="err">名前</span><span class="p">:</span> <span class="p">{{</span> <span class="nx">family</span><span class="p">.</span><span class="nx">name</span> <span class="p">}}</span>
        <span class="err">続柄</span><span class="p">:</span> <span class="p">{{</span> <span class="nx">family</span><span class="p">.</span><span class="nx">type</span> <span class="o">|</span> <span class="nx">family_type</span> <span class="p">}}</span>
      <span class="o"><</span><span class="sr">/li</span><span class="err">>
</span>    <span class="o"><</span><span class="sr">/ul</span><span class="err">>
</span>  <span class="err">,
  pipes: [FamilyTypePipe]
})
export class MyFamilyComponent { }

@Componentpipes プロパティに、importしたPipeを指定することで使用可能になります。
FamilyTypePipeが有効なのは、MyFamilyComponentのみです。

<ul>
  <li>
    名前: のび太
    続柄: 本人
  </li>
  <li>
    名前: のび太のパパ
    続柄: 父
  </li>
  <li>
    名前: のび太のママ
    続柄: 母
  </li>
  <li>
    名前: ドラえもん
    続柄: ロボット
  </li>
</ul>

同じコードを書くのが面倒…と思ったら

同じ処理の繰り返しにはカスタムパイプが威力を発揮します。
仕組みは簡単なので、ぜひ活用して独自のものを作ってみてください。
その便利さをすぐに実感できると思います。