Angularのパイプで日付・文字列を整える!標準パイプの一覧と自作パイプの作り方。
この記事では、Angularのパイプについて、日付・文字列を中心とした使い方と自作パイプの作り方などを説明する。
パイプは日付・数値・文字列などを特定のフォーマットに変換するための仕組みだ。
複雑なフォーマットなどはパイプを使わずとも実装できることが多いが、パイプを使うことによりスマートにそして再利用しやすい形で実装できることが多い。
自身のプロジェクトの中でもパイプを活用できる場面は多いはず。ぜひ使い方を覚えて可能ならばパイプを使って置き換えよう。
Angularのパイプとは?
パイプとは数字や日付などを希望するフォーマットに整形するための仕組み。
Angularには10数個のデフォルトパイプが備えられているが、自分でカスタムパイプを作成してプロジェクト内で使用することもできる。
インポートしたパイプはコンポーネント内でもテンプレート内でも呼び出すことができる。
パイプを使うことにより、ファイルの読みやすさを損ねることなく、パターンのフォーマットを実装することができる。
パイプの使い方
では、パイプをプロジェクトで使用してみよう。
テンプレート内で使用する
ここでは例として日付をフォーマットするパイプDatePipeを例として使用する。
まずはコンポーネント内にDateオブジェクトを作成してpublic にする。
public today = new Date();
テンプレート内でパイプを使用する。
<div>{{ today | date: 'medium' }}</div>
「date」でDatePipeを使用することを宣言している。
‘medium’は「MMM d, y, h:mm:ss a」というフォーマットを使うためのオプション。
アプリを実行すると「Nov 2, 2021, 9:28:56 PM」とフォーマットで現在の日付・時間が表示されるだろう。
コンポーネント内で使用する
次にコンポーネント内でDateオブジェクトを文字列に変換する例を見てみよう。
export class AppComponent {
public today: string;
constructor(private _datePipe: DatePipe) {
const date = new Date();
this.today = _datePipe.transform(date, 'full') as string;
}
}
コンストラクタでdatePipeを呼び出し、変換する際にはtransform関数を使用する。
<div>{{ today }}</div>
この例ではtodayがstring型なのでそのまま出力すればいい。
このようにDatePipeを使用する場合は、app.module.tsにてDatePipeをインポートする必要がある。
Angularの標準パイプ一覧
Angularが備えている標準のパイプとおもなメソッドを見ていこう。
日付 – DatePipe
DatePipeはもっともよく使われるパイプのひとつだろう。
Dateオブジェクトを基に日付や時間などを思い通りのフォーマットで出力することができる。
{{ value | date [ : format [ : timezone [ : locale ] ] ] }}
大文字・小文字 – UpperCasePipe・LowerCasePipe・TitleCasePipe
文字列の大文字・小文字を変換するパイプに「UpperCasePipe」「LowerCasePipe」「TitleCasePipe」の3つがある。
UpperCaseTipeは渡した文字列をすべて大文字に変換する。
{{ value | uppercase }}
LowerCaseTipeは渡した文字列をすべて小文字に変換する。
{{ value | lowercase }}
TitleCasePipeは入力した文字列の頭文字を大文字にそれ以外を小文字に変換する。
{{ value | titlecase }}
- “this is a Text” ⇒ “This Is A Text”
- “one,two,three” ⇒ “One,two,three”
- “rAnDom TExt” ⇒ “Random Text”
文字整形 – SlicePipe
SlicePipeは文字列を指定したインデックスの位置で切り抜く。
{{ value | slice : start [ : end ] }}
始まりの位置は常に指定するが、終わりの位置は任意である。
マイナスの数値をインデックスとして指定すると文字列の終わりから数えた位置が適用される。
数値 – DecimalPipe・PercentPipe・CurrencyPipe
DecimalPipeはオプションとローカルの設定に従って数値を整形するパイプ。
{{ value | number [ : digitsInfo [ : locale ] ] }}
PercentPipeはローカルの設定に従って数値をパーセントに整形するパイプ。
{{ value | percent [ : digitsInfo [ : locale ] ] }}
CurrencyPipeは入力したnumberを指定した通貨に変換するパイプ。
{{ value | currency [ : currencyCode [ : display [ : digitsInfo [ : locale ] ] ] ] }}
通貨はcurrencyCodeを使い指定する。日本円であれば「JPY」となる。
言語パイプ- I18nPluralPipe・I18nSelectPipe
I18nPluralPipeは数値を基に適切なテキストを呼び出すパイプ。
英語のように複数形において単語の末尾が変わるパターンで使用できる。
以下の例では、配列「persons」の要素数によってあらかじめ用意したmapから適切な語尾を選ぶようになっている。
public persons = ['Yutaka', 'Masayuki', 'Toshio'];
public textMap: {[k: string]: string} = {'=0': 'no one', '=1': '1 person', 'other': '# persons'};
{{ persons.length | i18nPlural: textMap }}
I18nSelectPipeはI18nPluralPipeに似ている。I18nSelectPipeでは入力した文字列に基づいて適切な文字列を返すパイプとなっている。
キーバリューパイプ – KeyValuePipe
KeyValuePipeはオブジェクトやMapのキーとバリューを出力するために使用するパイプ。
まずはコンポーネント側でオブジェクトかMapを用意する。
public animalMap = new Map([[1, 'cat'], [2, 'dog'], [12, 'panda']]);
テンプレート側ではkeyValuePipeを使用しながらngForを使ってMapを出力する。
<div *ngFor="let animal of animalMap | keyvalue">
{{animal.key}}: {{animal.value}}
</div>
JSONパイプ – JsonPipe
JSONパイプはJSONオブジェクトをテンプレート内で出力するためのパイプ。
JSONオブジェクトはJSONパイプを使わずにテンプレートで出力すると”[object Object]”と出力されてしまう。
実践でもよく活用できるパイプなので覚えておこう。
jsonObj = {
name: 'Taro',
age: 25,
address: {
prefecture: 'Tokyo',
Post: '123-4567'
}
};
<div>{{ jsonObj | json }}</div>
asyncパイプ – AsyncPipe
AsyncPipeはObservableやBehaviourSubjectといった非同期でアップデートされるオブジェクトを出力するためのパイプ。
public timeObserver = new Observable<string>((observer: Observer<string>) => {
setInterval(() => observer.next(new Date().toString()), 1000);
});
<div>現在の時間: {{ timeObserver | async }}</div>
カスタムパイプ(自作パイプ)の作り方
ここからは自分でオリジナルのパイプを作ってみよう。
ここでは入力された日付によって「本日」「昨日」といったテキストを表示するパイプを作ってみよう。
カレンダーやメッセンジャーアプリなどに使えるだろう。
カスタムパイプクラスの作成
最初にカスタムパイプのためのクラスを作成しよう。
カスタムパイプを作成するパイプもngコマンドを使用するのが早い。
ng generate pipe pipe/custom-date
transform関数の定義
パイプで変換をおこなうためにはtransform関数を定義しよう。
ここでは引数として渡されたDateオブジェクトから適切な文字列を出力するようにコードを記述する。
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'customDate'
})
export class CustomDatePipe implements PipeTransform {
public static isSameDay(d1: Date, d2:Date): boolean {
return d1.getFullYear() === d2.getFullYear() &&
d1.getMonth() === d2.getMonth() &&
d1.getDate() === d2.getDate();
}
public static isToday(date: Date): boolean {
const today = new Date();
return CustomDatePipe.isSameDay(date, today);
}
public static isYesterday(date: Date): boolean {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
return CustomDatePipe.isSameDay(date, yesterday);
}
transform(date: Date): string {
switch (true) {
case CustomDatePipe.isToday(date):
return '本日'
case CustomDatePipe.isYesterday(date):
return '昨日'
default:
return date.toLocaleDateString();
}
}
}
作成したパイプは以下のようにテンプレート内で呼び出せる。
<div>{{ date | customDate }}</div>