🐟

[Angular] パイプ基礎

2022/07/22に公開

パイプとは

テンプレート上に埋め込まれたデータを加工/ 整形するための仕組みです。
文字列、通貨金額、日付や、その他の表示データを書式設定するのに適しています。 Angularは複数のビルトインパイプを備えており、独自のパイプを作ることもできます。

補完バインディング{{}}の中で使われています。

テンプレートでプロパティなどを展開するときに使えます。

例えばhelloをHELLOと大文字にしたいときは、、

{{ "hello" | uppercase }}

など。

{{ 整形対象 | パイプ :'パラメータ'}}

|を連ねることで一つの整形対象に対して複数のパイプを適用できます。

ビルドインパイプ

Angularが用意してくれている、パイプです。

パイプ名 説明
lowercase 大文字から小文字に変換
uppercase 小文字から大文字に変換
titlecase 単語の先頭文字を大文字に変換
slice 文字列から部分文字列を切り出し
date 日付/時刻を整形
number 数値を桁区切り文字で整形
percent 数値を%形式に整形
json オブジェクトをJSON形式に変換
i18nPlural 数値によって表示文字列を変化
i18nSelect 文字列に応じて出力を切り替え
async Observable/Promiseによる非同期処理の結果を取得

lowercase

テキストをすべて小文字に変換します。

{{ value_expression | lowercase }}
const str = 'STRING';
----------------------
<p>{{ str | lowercase }}</p>

// 'string'

uppercase

テキストをすべて大文字に変換します。

{{ value_expression | uppercase }}
const str = 'string';
----------------------
<p>{{ str | uppercase}}</p>

// 'STRING'

titlecase

テキストをタイトルケースに変換します。

各単語の最初の文字を大文字にし、残りを小文字に変換します。

単語は、スペース、タブ、改行文字などの任意の空白文字で区切られます。

{{ value_expression | titlecase }}
<p>{{'some string' | titlecase}}</p>

// Some String

slice

文字列や配列から部分文字列を切り出せます。

str | slice: start[: end]

引数のendを省略した場合は、start時点から末尾までが切り出し対象になります。
startは取得開始位置
endは取得終了位置

💡 先頭(start)からのカウントは0番目から。
末尾(end)からのカウントは-1番目から。

例) str = ‘あいうえお’

str = 'あいうえお';

{{str | slice: 2 }}; // うえお
{{str | slice: 2 : 4}}; // うえ
{{str | slice: -3}}; // うえお
{{str | slice: -3 : -2}}; // う

date

日付の値を変換します。

{{ value_expression | date [ : format [ : timezone [ : locale ] ] ] }}
now = new Date();
-------------------------------
<p>{{ now | date:"yy/MM/dd HH:mm" }}</p>

// 22/07/22 07:45
{{ dateObj | date }}               // 'Jun 15, 2015'
{{ dateObj | date:'medium' }}      // 'Jun 15, 2015, 9:43:11 PM'
{{ dateObj | date:'shortTime' }}   // '9:43 PM'
{{ dateObj | date:'mm:ss' }}       // '43:11'

あらかじめ設定されているフォーマットオプション

オプション 該当する意味 値例
'short' 'M/d/yy, h:mm a' 6/15/15, 9:03 AM
'medium' 'MMM d, y, h:mm:ss a' Jun 15, 2015, 9:03:01 AM
'long' 'MMMM d, y, h:mm:ss a z' June 15, 2015 at 9:03:01 AM GMT+1
'full' 'EEEE, MMMM d, y, h:mm:ss a zzzz' Monday, June 15, 2015 at 9:03:01 AM GMT+01:00
'shortDate' 'M/d/yy' 6/15/15
'mediumDate' 'MMM d, y' 42170
'longDate' 'MMMM d, y' 42170
'fullDate' 'EEEE, MMMM d, y' Monday, June 15, 2015
'shortTime' 'h:mm a' 0.377083333
'mediumTime' 'h:mm:ss a' 0.377094907
'longTime' 'h:mm:ss a z' 9:03:01 AM GMT+1
'fullTime' 'h:mm:ss a zzzz' 9:03:01 AM GMT+01:00

カスタムフォーマットオプション

フィールドタイプ フォーマット 説明 値例
Era G, GG & GGG Abbreviated AD
GGGG Wide Anno Domini
GGGGG Narrow A
Year y Numeric: minimum digits 2, 20, 201, 2017, 20173
yy Numeric: 2 digits + zero padded 02, 20, 01, 17, 73
yyy Numeric: 3 digits + zero padded 002, 020, 201, 2017, 20173
yyyy Numeric: 4 digits or more + zero padded 0002, 0020, 0201, 2017, 20173
Week-numbering year Y Numeric: minimum digits 2, 20, 201, 2017, 20173
YY Numeric: 2 digits + zero padded 02, 20, 01, 17, 73
YYY Numeric: 3 digits + zero padded 002, 020, 201, 2017, 20173
YYYY Numeric: 4 digits or more + zero padded 0002, 0020, 0201, 2017, 20173
Month M Numeric: 1 digit 9, 12
MM Numeric: 2 digits + zero padded 09, 12
MMM Abbreviated Sep
MMMM Wide September
MMMMM Narrow S
Month standalone L Numeric: 1 digit 9, 12
LL Numeric: 2 digits + zero padded 09, 12
LLL Abbreviated Sep
LLLL Wide September
LLLLL Narrow S
Week of year w Numeric: minimum digits 1... 53
ww Numeric: 2 digits + zero padded 01... 53
Week of month W Numeric: 1 digit 1... 5
Day of month d Numeric: minimum digits 1
dd Numeric: 2 digits + zero padded 1
Week day E, EE & EEE Abbreviated Tue
EEEE Wide Tuesday
EEEEE Narrow T
EEEEEE Short Tu
Week day standalone c, cc Numeric: 1 digit 2
ccc Abbreviated Tue
cccc Wide Tuesday
ccccc Narrow T
cccccc Short Tu
Period a, aa & aaa Abbreviated am/pm or AM/PM
aaaa Wide (fallback to a when missing) ante meridiem/post meridiem
aaaaa Narrow a/p
Period* B, BB & BBB Abbreviated mid.
BBBB Wide am, pm, midnight, noon, morning, afternoon, evening, night
BBBBB Narrow md
Period standalone* b, bb & bbb Abbreviated mid.
bbbb Wide am, pm, midnight, noon, morning, afternoon, evening, night
bbbbb Narrow md
Hour 1-12 h Numeric: minimum digits 1, 12
hh Numeric: 2 digits + zero padded 01, 12
Hour 0-23 H Numeric: minimum digits 0, 23
HH Numeric: 2 digits + zero padded 00, 23
Minute m Numeric: minimum digits 8, 59
mm Numeric: 2 digits + zero padded 08, 59
Second s Numeric: minimum digits 0... 59
ss Numeric: 2 digits + zero padded 00... 59
Fractional seconds S Numeric: 1 digit 0... 9
SS Numeric: 2 digits + zero padded 00... 99
SSS Numeric: 3 digits + zero padded (= milliseconds) 000... 999
Zone z, zz & zzz Short specific non location format (fallback to O) GMT-8
zzzz Long specific non location format (fallback to OOOO) GMT-08:00
Z, ZZ & ZZZ ISO8601 basic format -800
ZZZZ Long localized GMT format GMT-8:00
ZZZZZ ISO8601 extended format + Z indicator for offset 0 (= XXXXX) -08:00
O, OO & OOO Short localized GMT format GMT-8
OOOO Long localized GMT format GMT-08:00

number (Decimal)

数字オプションとロケール規則に従って値をフォーマットする。ロケールは、グループの大きさや区切り、小数点以下の文字、その他ロケール特有の設定を決定する。

{{ value_expression | number [ : digitsInfo [ : locale ] ] }}
pi: number = 3.14159265359;
------------------------
<p>
  フォーマットなし:
  {{pi | number}}
  <!--output: '3.142'-->
</p>

<p>
  digitsInfo パラメータを指定した場合:
  {{pi | number:'4.1-5'}}
  <!--output: '0,003.14159'-->
</p>

数字情報

値の10進数表現はdigitsInfoパラメータで指定し、以下のフォーマットで記述する。

minIntegerDigits.minFractionDigits-maxFractionDigits
  • minIntegerDigits: 小数点の前の整数の最小桁数。デフォルトは1。
  • minFractionDigits: 小数点以下の最小桁数を指定します。デフォルトは0。
  • maxFractionDigits: 小数点以下の最大桁数。デフォルトは3。

percent

数値からパーセント文字列に変換し、グループのサイズや区切り、小数点以下の文字、その他のロケール特有の設定を決定するロケール規則に従ってフォーマットする。

{{ value_expression | percent [ : digitsInfo [ : locale ] ] }}
a: number = 0.259;
b: number = 1.3495;
-----------------------------
<div>
  <!--output '26%'-->
  <p>A: {{a | percent}}</p>

  <!--output '0,134.950%'-->
  <p>B: {{b | percent:'4.3-5'}}</p>
</div>

json

値をJSON形式の表現に変換する。デバッグに便利。

{{ value_expression | json }}
object: Object = {foo: 'bar', baz: 'qux', 
nested: {xyz: 3, numbers: [1, 2, 3, 4, 5]}};
---------------------------------------------------------
<div>
  <p>Without JSON pipe:</p>
  <pre>{{object}}</pre>
  <p>With JSON pipe:</p>
  <pre>{{object | json}}</pre>
</div>

// {
//   "foo": "bar",
//   "baz": "qux",
//   "nested": {
//     "xyz": 3,
//     "numbers": [
//       1,
//       2,
//       3,
//       4,
//       5
//     ]
//   }
// }

i18nPlural

値をロケール規則に従って複数化した文字列にマップする。

{{ value_expression | i18nPlural : pluralMap [ : locale ] }}
messages: any[] = ['Message 1'];
messageMapping: {[ k: string]: string } =
	{ '=0': 'No messages.', '=1': 'One message.', 'other': '# messages.' };
--------------------------------------------------------------------------
<div>{{ messages.length | i18nPlural: messageMapping }}</div>

// One message.

i18nSelect

現在の値にマッチする文字列を表示する汎用セレクタ。

{{ value_expression | i18nSelect : mapping }}{{ value_expression | i18nSelect : mapping }}
gender: string = 'male';
inviteMap: any = 
  {'male': 'Invite him.', 'female': 'Invite her.', 'other': 'Invite them.'};
------------------------------------------------------------------------------
<div>{{gender | i18nSelect: inviteMap}} </div>

// Invite him.
  • mapping : 提供された値の異なる値に対して表示されるべきテキストを示すオブジェクト。

async

async pipeはpromiseやobservableな非同期オブジェクトをそのままtemplateで表示できるようにしたpipeです。
asyncパイプを利用するとビュー側でObservableオブジェクトを受け取り、それらが値を返したタイミングでその値を取り出すことができます。

{{ obj_expression | async }}

下記はngFor文です。

<li *ngFor="let hero of heroes$ | async" >
  <a routerLink="/detail/{{hero.id}}">
    {{hero.name}}
  </a>
</li>

または

import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';

import 'rxjs/add/operator/map';

@Component({
  selector: 'my-app',
  template: `
    <div>
      サーバーからのメッセージ:{{message | async}}
    </div>
  `
})
export class AppComponent {
  message: Observable<string>;

  constructor(private http: Http) { }

  ngOnInit() {
    this.message = this.http.get('app/message.txt')
      .map(response => response.text());
  }
}
  • messageパラメータはObservable型です。
  • 受け取ったObservable型の値をそのままテンプレートに出すにはasyncパイプを使うということです。

async as

ngIf文ではasを使うと評価結果を変数化できます。
下記の場合、user$の値をuserに入れなさいという意味
asによって作られた変数はngifのディレクティブ配下のみで参照できます。

<div *ngIf="user$ | async as user">
    <p>{{ user.name }}</p>
    <p>{{ user.age }}</p>
    <img [src]="user.icon">
</div>
  • user$userにしてテンプレートで変数として使う

[Angular 4.0] 新しいngIfの使い方

カスタムパイプ

パイプを自作することができます。

カスタムパイプでフォーマットの共通化

先ほど作成した日付のフォーマットを共通化します。

まずはカスタムパイプを定義するファイルを作成します。

ng g pipe pipes/comment-date

src\app\pipes\comment-date.pipe.ts

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

@Pipe({
  // パイプの名前
  name: 'commentDate'
})
export class CommentDatePipe implements PipeTransform {

  // メインメソッド
  transform(value: number, ...args: string[]): string {
    const format = args[0] || 'yyyy年MM月dd日 HH:mm';
    return formatDate(value, format, 'en-US');
  }

}
  • テンプレートでパイプを記述するときにcommentDateとすることで呼び出せます。
  • transformメソッドがこのパイプを呼び出したときのメインメソッドとなります。
  • formatDateをインポートすることでformatDateメソッドが使えます。
  • パイプでcommentDateのみ記述した場合は'yyyy年MM月dd日 HH:mm'が適応されます。もし任意の文字列でフォーマットを指定した場合は、args配列で受け取り、それが適応されます。

テンプレート

class="media-date">{{ comment.date | commentDate }}
-------------------------------------------------------
class="media-date">{{ comment.date | commentDate: 'MM月dd日' }} のようにカスタムも可能

参考

https://angular.jp/guide/pipes

https://angular.keicode.com/basics/pipes.php

https://qiita.com/NS19960207/items/d5b0868687c2d3d5b0cf#:~:text=Angular パイプとは,を整形する機能」です。

Discussion