Angular基礎 データ変換機能 Pipeの使い方

pipeThum Angular基礎
200 DegreesによるPixabayからの画像

この記事ではAngularの基本機能の一つpipe(パイプ)について、解説してします。

pipeとはインプットしたデータを表示したいスタイルに変換するAngularの持つ機能の一つです。

pipeを使うことで、データを変換するコードを省くことができるので、より効率的にアプリ開発を進めることができます。

pipeにはBuilt-in pipeとCustom pipeがあります。

この記事を読み終わるとPipeとは何か、どのように使うのかが分かるようになります。

Built-in pipeの種類と使い方

Built-in pipeはAngularが提供するpipeです。

今回は下の7つのBuild-in pipeを紹介します。

  • lowercase:インプットされたstringの文字を全て小文字で表示する
  • uppercase:インプットされたstringの文字を全て大文字で表示する
  • decimal:インプットされた数字の整数と少数を決められた形で表示する
  • currency:インプットされた数字に通貨を入れる
  • date:インプットされた数字を日にちとして表示する
  • percent:インプットされた数字をパーセントとして表示する
  • slice:インプットされた配列の中で指定された要素を表示する

pipeはHTMLテンプレートファイルの中で、下のように表記します。

 {{ データの値 | pipeのタイプ: “パラメーター” }}

データにはstringや数字を直接入れることも出来ますが、コンポーネント(typescriptファイル)で変数を宣言し、データを代入することが多いです。

※パラメーターはオプショナルなので、必要な場合のみつけることが出来ます。

※パラメーターを入れる場合はダブルクォーテーション “ “もしくはシングルクォーテーションが必要です。

lowercaseとuppercase

文字通りlowercaseは表示するデータを小文字に、uppercaseは大文字に統一してくれます。

Typescriptファイル

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass'],
})
export class AppComponent {
  //lowerCaseという変数を宣言し、大文字と小文字の混ざったstringを入れる。
  lowerCase= "Taro YAMADA";
}


データの値に代入する変数lowerCaseをTypescriptファイルで宣言します。

HTMLファイル

<h2>Lowercase pipe</h2>
<!-- Typescriptファイルで宣言したlowerCaseという変数をデータとして入れる -->
<div ngNonBindable>User name: {{ lowerCase | lowercase }} </div>
<div>User name: <span>{{ lowerCase | lowercase }} </span></div>

<h2>Uppercase pipe</h2>
<!-- "uppercase"というstringを直接データとして入れる-->
<div ngNonBindable>User name: {{ "uppercase" | uppercase }} </div>
<div>User name: <span>{{ "uppercase"  | uppercase }} </span></div>

lowercaseの値にはtypescriptファイルで宣言した変数lowerCaseを代入し、uppercaseの例では、”uppercase”という全小文字のstringを直接値に代入します。

lowercaseの例では、変数に代入したTaro YAMADAが全て小文字に、uppercaseの例では値に代入したuppercaseというstringデータが全て大文字で表示されました。

decimal pipe

次にdecimalの例を見ていきましょう。

Decimalとは十進法や小数を意味します。

入力した数字の整数の数と小数点以下、第何位までを表示するかを指定できます。

{{ データの値(数字またはnumber型の変数) | number: “パラメーター” }}

Decimal pipeのタイプはnumberで表し、必ずパラメーターを伴います。

{{ 123. 4567 | number: “3.1-2” }}
  • パラメータの第1引数:整数の数。
  • パラメータの第2引数:小数点以下の最低数。
  • パラメータの第3引数:小数点以下の最高数。

上の例の場合、パラメータの第1引数が3なので、整数部分は123。

小数点以下の数字が小数第4位まであって、パラメータの第2引数が1、且つ第3引数が2なので、2が適用されて、123.45がとなります。

{{ 123 | number: “3.1-2” }}

上のように整数のみの場合、パラメータの第2引数が1が適用されて123.0となります。

HTMLファイル

<h2>Decimal pipe</h2>
<div ngNonBindable>今日の体温は{{ 35.789 | number: '2.1-1' }}です。 </div>
<div>今日の体温は{{ 35.789 | number: '2.1-1' }}です。</div>
<hr>
<div ngNonBindable>今日の体温は{{ 35.789 | number: '2.1-3' }}です。</div>
<div>今日の体温は{{ 35.789 | number: '2.1-3' }}です。</div>

currency pipe

Currencyのpipeはインプットした数字に通貨を加えてくれます。

TypescriptファイルでcurrencyDataという変数を宣言し、数字を代入します。

Typescriptファイル

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass'],
})
export class AppComponent {
  //currencyDataという変数を宣言し、数字を入れる。
  currencyData= 6000.12345;
}


HTMLファイル

<h2>Currency pipe</h2>
<!-- データ部分に直接、数字を入れる -->
<div ngNonBindable>今月の売り上げ: {{ 5500.095 | currency }} </div>
<div>今月の売り上げ: <span>{{ 5500.095 | currency }} </span></div>

<!-- Typescriptファイルで宣言したcurrencyDataという変数をデータとして入れる-->
<div ngNonBindable>今月の売り上げ: {{ currencyData| currency: "usd" }} </div>
<div>今月の売り上げ: <span>: {{ currencyData| currency: "usd" }} </span></div>

Currency pipeはパラメーターを指定しない場合、デフォルトで”USD”になっています。

パラメーターを大文字で記載した場合、通貨の記号で表示されるので、一番目の例で$が入っています。

2番目の例のように小文字で”usd”と記載した場合は、文字で表示されます。

日本円の場合は次のようになります。

HTMLファイル

<h2>Currency pipe</h2>
<div ngNonBindable>今月のお小遣い: {{ 5500.095 | currency: "JPY" }} </div>
<div>今月のお小遣い: <span>{{ 5500.095 | currency: 'JPY'}} </span></div>
<hr>
<div ngNonBindable>今月のお小遣い: {{ 5500.095 | currency: 'jpy' }} </div>
<div>今月のお小遣い: <span>{{ 5500.095 | currency: 'jpy' }} </span></div>
<hr>
<div ngNonBindable>今月のお小遣い: {{ 5500.095 | currency: 'jpy': 'symbol': '4.0-0' }}</div>
<div>今月のお小遣い: <span>{{ 5500.095 | currency: 'jpy': 'symbol': '4.0-0' }} </span></div>

2番目の例のようにパラメーターを小数で記載した場合(”jpy”)、currency pipeのデフォルトで、小数第2位まで表示される設定になっています。

日本円は小数点以下は存在しないので、この場合、3番目の例のように”symbol: 4.0-0”という追加のパラメーターを使うことで小数点以下を四捨五入することができます。

date pipe

date pipeも様々なパラメーターを設定することで表示の仕方を自由に変更することができます。

typescriptファイル内でtodayという変数を宣言し、現在の日時を代入します。

Typescriptファイル

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass'],
})
export class AppComponent {
  //todayという変数を宣言し、現在の日時を入れる。
  today= Date.now();
}


HTMLファイル

<h2>Date pipe</h2>
<div ngNonBindable>今日は{{ today | date }} です</div>
<div>今日は{{ today | date }} です</div>
<hr>
<div ngNonBindable>今日は{{ today | date : 'short'}}です</div>
<div>今日は{{ today | date : 'short'}}です</div>
<hr>
<div ngNonBindable>今日は {{ today | date : 'medium'}} です</div>
<div>今日は {{ today | date : 'medium'}} です</div>
<hr>
<div ngNonBindable>今日は{{ today | date : 'long'}}です</div>
<div>今日は{{ today | date : 'long'}}です</div>

Date pipeのパラメーターとして入力できるオプションはAngularのこちらのサイトで確認できます。

percent pipe

typescriptファイルでpercentという変数を宣言し、表示したい数字÷100を代入します。

Typescriptファイル

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass'],
})
export class AppComponent {
  //percentという変数を宣言し、百分率の数字を入れる。
  percent= 0.987654 
}


HTMLファイル

<h2>Percent pipe</h2>
  <div ngNonBindable>今日の降水確率は{{ 0.123456 | percent }}です。 </div>
  <div>今日の降水確率は{{ 0.123456 | percent }}です。 </div>
  <hr>
  <div ngNonBindable>目標達成率は{{ percent | percent: '2.2-2' }}です。 </div>
  <div>目標達成率は {{ percent | percent: '2.2-2' }}です。</div>

1番目の例のようにパラメーターを通さない場合は、整数でパーセントが表示されます。

小数点まで指定したい場合は、パラメータ―を設定しましょう。

slice pipe

slice pipeは配列から指定する要素だけを取り出したり、stringから指定する文字だけを取り出すパイプです。

{{ データの値(strngまたはarray型、もしくはその変数) |slice: “パラメーター” }}

slice pipeのタイプも必ずパラメーターを伴います。

{{ “abcde” | slice: 1 : 4 }} 

パラメータの第1引数:

表示したい最初の文字または配列要素のインデックス。

上の例の場合、第1引数が1なのでbから。

配列なので、カウントは0から始まる。

パラメータの第2引数:

表示したい最後の文字、または配列要素のインデックス+1。

上の例の場合、第1引数が4なのでdまで。

つまりアウトプットはbcdになります。

Typescriptファイル

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass'],
})
export class AppComponent {
  //itemsという配列変数を宣言し、要素を入れる。
  items: string[]= ['商品A', '商品B','商品C','商品D']
}


HTMLファイル

<h2>Slice pipe</h2>
    <div>配列の例</div>
    <ul><li *ngFor="let i of items | slice:1:3">{{i}}</li></ul>
    <hr>
    <div>stringの例</div>
    <div>{{ "012345" | slice: 1 : 5 }}</div>

Custom pipeの作り方

Custom pipeを作ることで、自分が指定するデータ表示に変換する機能を作ることが出来ます。

今回、プロパティの値によって異なる背景色を追加するパイプを作成してみました。

ステップは4つです。

ステップ①: CLIコマンドを使ってcustom pipeファイルを作成

ng generate pipe パイプ名
Pipeファイル

//Pipe, PipeTransformを自動的にインポートしてくれる
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
  name: 'customPipe'
})
export class CustomPipePipe implements PipeTransform {
  //下のtransformのファンクションを自動的に追加してくれる
  transform(value: unknown, ...args: unknown[]): unknown {
    return null;
  }
}

CLIコマンドを使ってパイプファイルを作成すると自動的にPipeとPipeTransformパッケージを@angular/coreからインポートしてくれます。

インポートの下にはパイプ名customPipeが自動的に作成されます。

また、クラス内にはtransformというファンクションも追加してくれます。

Transformの第一パラメーターにはバインディングするデータを、第二パラメーターには自分の受け取りたいデータを設定できます。

ステップ②: Typescriptファイルで表示したいデータを作成

今回dataというオブジェクト変数を作り、name/ city/ ageという3つのプロパティを入れました。

Typescriptファイル

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass'],
})
export class AppComponent {
  // //dataという変数を作り、name/ city/ age情報を入れる
  data = {
    name: "Ken Ito",
    city: "Tokyo",
    age: 27
  }
}

ステップ➂: HTMLファイルを設定

divタグ内にinnerHTMLをバインディングし、Typescriptファイルで作ったデータのプロパティをそれぞれ入れます。

パイプとして上で作成したcustomPipeを入れます。

HTMLファイル

<h2>Custom pipe</h2>
<div [innerHTML]= "data.name | customPipe"></div>
<div [innerHTML]= "data.city | customPipe"></div>
<div [innerHTML]= "data.age | customPipe"></div> 

ステップ➃: Pipeファイルの設定

Pipeファイル

//下を自動的にインポートしてくれる
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({
  name: 'customPipe'
})
export class CustomPipePipe implements PipeTransform {
  //HTMLファイルで設定したinnerHTMLをバインディングするために
  //DomSanitizerをインポート&インスタンス化する
  constructor(private domSanitaizer: DomSanitizer) { }
  //下のtransformのファンクションを自動的に追加してくれる
  transform(value: any): any {
    //もしデータの値がTokyoなら
    if (value === 'Tokyo') {
      //背景色をライトグリーンにする
      return this.domSanitaizer.bypassSecurityTrustHtml
      ('<div style="background-color: lightgreen">' + value + '</div>');
    }
    else {
      //それ以外の場合、背景色を黄色にする
      return this.domSanitaizer.bypassSecurityTrustHtml
      ('<div style="background-color: yellow">' + value + '</div>');
    }
  }
}

transformファンクションで背景色を返したい場合、タグにスタイルを追加する必要があります(上の写真の17行目、22行目のdivタグ)。

HTMLファイルでバインディングする(表示する)際に必要なDomSanitizerをインポートします。

インポートしたDomSanitizerはコンストラクタでインスタンス化しておきます。

TypescriptファイルやpipeファイルのデータをHTMLに表示するとき、Angularではインターポレーション {{ }} が使われることが多いですが、インターポレーションはタグをstringとして表示してしまうので、今回はinnerHTMLとDomSanitizerを使いました。

transformのパラメーターを通してtypescriptで作ったデータのプロパティの値(”Ken Ito”/ “Tokyo”/ 27)を受け取りたいので、パラメーター名value、any型でデータを受け取るよう設定します(プロパティの値はstring型とnumber型の両方なので)。

もし値(value)がTokyoならば背景色をライトグリーンにし、それ以外は黄色にします。

設定した通り、Tokyoの部分だけ背景がライトグリーンになりました。

まとめ

各パイプ機能を簡単にまとめてみましたが、いかがでしたか?

パイプを使いこなすことが出来るとViewの設定がとても楽になります。

本記事が皆さんのアプリ開発の役に立てば嬉しいです。

タイトルとURLをコピーしました