SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

次世代Webアプリケーションフレームワーク「Angular」の活用

「Angular」の変数を見やすい形式に変換して表示できるPipesの活用法

次世代Webアプリケーションフレームワーク「Angular」の活用 第10回

組み込みPipesで対応できない変換をカスタムPipesで実現

 組み込みPipesで対応できない変換は、カスタムPipesを実装して実現できます。図6のような数値を2進数/8進数/16進数に変換して表示するサンプルで、カスタムPipesの実装方法を説明します。

図6 カスタムPipesでn進数変換(004-custom)
図6 カスタムPipesでn進数変換(004-custom)

 このカスタムPipesの実装はリスト7のようになります。

リスト7 カスタムPipesの実装(004-custom/src/app/numberbase.pipe.ts)
// カスタムPipesの記述に必要な変数を参照 ...(1)
import { Pipe, PipeTransform } from '@angular/core';

// Pipes宣言と名前の指定 ...(2)
@Pipe({name: "base"})
export class NumberBasePipe implements PipeTransform {
  // PipeTransformインタフェースのtransformメソッド ...(3)
  transform(valueString: string, base:number): string {
    console.log("NumberBasePipe value=" + valueString + ", base=" + base);
    // 入力文字列を数値に変換(変換できないときは入力文字列を返却) ...(4)
    let value = Number.parseInt(valueString);
    if (isNaN(value)) { return valueString; }
    // 2進数の場合 ...(5)
    if (base === 2) {
      return "0b" + value.toString(base);
    }
    // 8進数の場合 ...(6)
    else if (base === 8) {
      return "0o" + value.toString(base);
    }
    // 16進数の場合 ...(7)
    else if (base === 16) {
      return "0x" + value.toString(base);
    }
    // それ以外の場合は10進数として扱う ...(8)
    else {
      return value.toString();
    }
  }
}

 (1)で、カスタムPipesに必要なPipeデコレーターとPipeTransformインタフェースを参照しています。(2)のようにPipeデコレーターに名前(base)を指定して、PipeのクラスNumberBasePipeを定義しています。

 Pipesの変換処理は、PipeTransformインタフェースで定義されるtransformメソッド(3)に実装します。transformメソッドの第1引数には変換前の変数、第2引数以降は「:」で区切って指定するパラメーターが渡されるので、これらから変換後の文字列を作成して返却するよう実装します。まず、変換前の変数valueStringを(4)で数値に変換します。数値に変換できないときはvalueStringの値をそのまま返却して処理を終了し、変換できた場合は基数パラメーターbaseの値に応じて(5)~(7)で2進数/8進数/16進数に変換して返却します。基数が2、8、16のいずれでもない場合は、(8)で10進数をそのまま返却します。

 リスト7のカスタムPipesを利用するには、モジュール定義ファイルapp.modules.tsにリスト8の(1)(2)のように記述して、カスタムPipesを設定します。

リスト8 カスタムPipesの設定(004-custom/src/app/app.modules.ts)
// カスタムPipesの参照 ...(1)
import { NumberBasePipe } from "./numberbase.pipe";
@NgModule({
(略)
  declarations: [
    AppComponent,
    NumberBasePipe // カスタムPipesを設定 ...(2)
  ],
(略)
})

 カスタムPipesはコンポーネントでリスト9のように利用できます。「base:」の後のパラメーターに、2進数/8進数/16進数のどれに変換するかを数字で指定します。

リスト9 カスタムPipesの利用(004-custom/src/app/app.component.ts)
<div>2進数:{{inputValue | base:2}}</div>
<div>8進数:{{inputValue | base:8}}</div>
<div>16進数:{{inputValue | base:16}}</div>

Angularの変更監視処理とPure Pipes/Impure Pipesの関係

 ここまで説明してきたPipesは、Angularの変更監視処理で、文字や数値の変更やオブジェクトが置換されたことを検出したときのみ実行されます。このようなPipesを「Pure Pipes」と呼びます。

 Angularは、オブジェクトの内容変更(Date型オブジェクトの年だけを変更する場合や、配列への要素追加など)を無視するため、このときPure Pipesは実行されません。オブジェクトの内容変更時にPipesを実行させる場合は、PureでないPipes(「Impure pipes」)にする必要があります。例えば、リスト7のカスタムPipesをImpure pipesにするには、リスト10のように@Pipeデコレーターのpure変数にfalseを指定します。

リスト10 Impure pipesの利用(004a-impure/src/app/numberbase.pipe.ts)
// Pipes宣言と名前の指定
@Pipe({
  name: "base",
  pure: false
})

 Impure pipesは、Angularの変更監視処理の都度、変更を検出したかどうかにかかわらず実行されます。リスト10を実行してデバッグログを表示させると、ページロード時やテキストボックスのフォーカス変更時などに、頻繁にPipesが実行されます。

図7 Impure pipesの実行頻度(004a-impure)
図7 Impure pipesの実行頻度(004a-impure)

 一方、Pure pipes(リスト7)はページロード時の初回に1回だけ実行され、テキストボックスのフォーカスを変更しても、値が変更されなければ実行されません。

図8 Pure pipesの実行頻度(004-custom)
図8 Pure pipesの実行頻度(004-custom)

 Impure pipesは実行頻度が高いため、カスタムPipesは可能な限りPure pipesとするのが望ましいです。どうしてもImpureにするときは、Pipes内で重たい処理が繰り返し実行されないように注意して実装する必要があります。

[補足]AngularJS 1のfilterとorderbyに対応するPipesが存在しないわけ

 Angularには、配列のインデックスで範囲を指定するPipes(SlicePipe)が存在しますが、フィルターや並び替えを行うPipesは存在しません。AngularJS 1にはfilterやorderbyとして存在していましたが、Angularでは以下の理由から意図的に実装されていません。

  • フィルターや並び替えの処理はオブジェクト配列が対象となるため、上述のImpure Pipesにする必要があり、実行速度の低下が懸念されること。
  • フィルターや並び替えの条件として指定するプロパティ名が、JavaScriptの最小化で別の名前に変更されて問題を起こす可能性があること。

 フィルターや並び替えの処理は、Pipesではなくコンポーネントに直接実装するよう、Angularの公式ドキュメントで案内されています。

まとめ

 本記事では、変数を表示用に変換するAngularのPipesについて説明しました。Pipesを利用すると、画面表示のための変換処理をコンポーネントの処理から分離して、柔軟な画面表示を実現できます。利用頻度が高い変換はAngularが標準で用意しているほか、カスタムPipesでより細かい変換処理を作り込むこともできます。

参考資料

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
次世代Webアプリケーションフレームワーク「Angular」の活用連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10237 2017/06/22 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー