前言

Pipe 是 Angular 中用來轉換資料的方式,讓我們可以在 Template 中對資料進行格式化或轉換,並且可以在程式碼中重複利用。這篇文章將介紹內建 Pipe 和如何建立自訂 Pipe。

Pipe 用途

Angular 的 Pipe 是一種轉換資料的方式,它可以用在 Template 中對資料進行格式化或轉換等操作,並可以在程式碼中進行重複利用。

Pipe 可以分為兩種類型:

  • Angular 內建 Pipe:Angular 提供如 DatePipeUpperCasePipe
  • 自訂 Pipe:開發者自行建立的 Pipe

內建 Pipe

只需要在模板中使用管道符號 | 來調用 Pipe 即可。以下是一些常用的內建 Pipe:

DatePipe

格式化日期。

<p>{{ today | date:'yyyy-MM-dd' }}</p>
<!-- 輸出:2023-03-17 -->

<p>{{ today | date:'fullDate' }}</p>
<!-- 輸出:Friday, March 17, 2023 -->

UpperCasePipe / LowerCasePipe

將文字轉為大寫或小寫。

<p>{{ name | uppercase }}</p>
<!-- 輸出:JOHN -->

<p>{{ name | lowercase }}</p>
<!-- 輸出:john -->

CurrencyPipe

格式化金額。

<p>{{ price | currency:'USD' }}</p>
<!-- 輸出:$1,234.56 -->

<p>{{ price | currency:'TWD':'symbol-narrow' }}</p>
<!-- 輸出:NT$1,234.56 -->

PercentPipe

格式化百分比。

<p>{{ rate | percent }}</p>
<!-- 輸出:75% -->

<p>{{ rate | percent:'1.2-2' }}</p>
<!-- 輸出:75.50% -->

DecimalPipe

格式化數字。

<p>{{ number | number:'1.2-2' }}</p>
<!-- 1.2-2 表示:至少 1 位整數,2-2 位小數 -->

AsyncPipe

處理非同步資料(Observable 或 Promise)。

<p>{{ data$ | async }}</p>

在 Component 中:

import { Observable } from 'rxjs';

export class AppComponent {
  data$: Observable<string>;
  
  constructor(private http: HttpClient) {
    this.data$ = this.http.get<string>('/api/data');
  }
}

自訂 Pipe

可以自行撰寫 Pipe,擴充 Angular 的 Pipe 功能。需要實作 PipeTransform Interface,該介面只有一個 transform 方法,負責處理資料轉換。

建立自訂 Pipe

使用 Angular CLI 建立:

ng generate pipe double

範例:建立一個將數字乘以 2 的 Pipe

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

// Pipe 裝飾器
@Pipe({
  name: "double"
})
// 實作 PipeTransform Interface
export class DoublePipe implements PipeTransform {
  transform(value: number): number {
    return value * 2;
  }
}

使用方式:

<p>{{ 5 | double }}</p>
<!-- 輸出:10 -->

帶參數的 Pipe

Pipe 也可以接收參數。

範例:建立一個可以指定倍數的 Pipe

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

@Pipe({
  name: "multiply"
})
export class MultiplyPipe implements PipeTransform {
  transform(value: number, multiplier: number = 1): number {
    return value * multiplier;
  }
}

使用方式:

<p>{{ 5 | multiply:3 }}</p>
<!-- 輸出:15 -->

<p>{{ 5 | multiply }}</p>
<!-- 輸出:5 (使用預設值 1) -->

實用範例:文字截斷 Pipe

建立一個截斷長文字的 Pipe:

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

@Pipe({
  name: "truncate"
})
export class TruncatePipe implements PipeTransform {
  transform(value: string, limit: number = 50, ellipsis: string = '...'): string {
    if (!value) return '';
    if (value.length <= limit) return value;
    return value.substring(0, limit) + ellipsis;
  }
}

使用方式:

<p>{{ longText | truncate:20 }}</p>
<!-- 只顯示前 20 個字元,後面加上 ... -->

鏈結多個 Pipe

可以將多個 Pipe 串連使用:

<p>{{ today | date:'fullDate' | uppercase }}</p>
<!-- 先格式化日期,再轉大寫 -->

<p>{{ price | currency:'USD' | lowercase }}</p>

Pure Pipe vs Impure Pipe

預設情況下,Pipe 是 Pure Pipe,只有在輸入值改變時才會重新執行。如果需要在每次變更檢測時都執行,可以設定為 Impure Pipe

@Pipe({
  name: "myPipe",
  pure: false  // 設定為 Impure Pipe
})
export class MyPipe implements PipeTransform {
  transform(value: any): any {
    // 處理邏輯
  }
}

注意:Impure Pipe 會影響效能,應謹慎使用。

總結

Angular Pipe 是格式化和轉換資料的強大工具:

  • 內建 Pipe:提供常用的日期、數字、文字格式化功能
  • 自訂 Pipe:可以建立符合需求的資料轉換邏輯
  • 可串連使用:多個 Pipe 可以組合使用
  • 支援參數:Pipe 可以接收參數來客製化行為

善用 Pipe 可以讓 Template 更加簡潔,提高程式碼的可讀性和可維護性。

參考資料