0%

Angular 筆記 - 使用 Pipe 轉千分位共用管道

angular

在工作上有一個需要轉千分位的需求,做個紀錄,專案使用 Angular 開發。

需求

規格書文件中提到以下需求:

  1. 有一筆資料有字串有數字,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
data = [
{
name: "iphone",
price: 35000,
},
{
name: "phone case",
price: 880,
},
{
name: "battery",
price: 990,
},
{
name: "Macbook pro",
price: 41500,
},
];
  1. 當超過 1000 的價格要使用千分位顯示,若不到 1000 就顯示原本的數字。

解決方式

因後端有多筆資料,故可以使用 Pipe 做一個共用管道,當數值丟進來時,可以去做轉換顯示。

先把資料渲染出來確認無誤

這邊使用 table 當作資料呈現方式,樣式則使用 TailwindCSS 來製作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<div class="p-3">
<h1 class="py-2 text-purple-500 tracking-wide">
使用 Pipe 成為共用管道轉成「千分位數」
</h1>
<p>當超過 1000 就加上逗號區隔,若沒有就顯示原本的數值</p>

<table class=" border-2 border-purple-700 w-full">
<thead class=" bg-purple-700 text-white">
<tr>
<th class="py-2 px-4 text-center">品項</th>
<th class="py-2 px-4 text-center">價格</th>
<th class="py-2 px-4 text-center">品項</th>
<th class="py-2 px-4 text-center">價格</th>
<th class="py-2 px-4 text-center">品項</th>
<th class="py-2 px-4 text-center">價格</th>
<th class="py-2 px-4 text-center">品項</th>
<th class="py-2 px-4 text-center">價格</th>
</tr>
</thead>
<tbody>
<tr>
<ng-container *ngFor="let item of data">
<td class="py-2 px-4 text-center border-purple-700 border-2 ">
{{item.name}}
</td>
<td class="px-4 py-2 text-center border-purple-700 border-2">
{{item.price}}
</td>
</ng-container>
</tr>
</tbody>
</table>
</div>

利用 ng-container 標籤中使用 ngFor 把資料渲染在 td 上,這樣比較不會破壞網頁架構。

建立 pipe 管道

新增一個 pipe 檔案,這邊我使用 toThousand.pipe.ts,並在裡面寫上要處理的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Pipe, PipeTransform } from "@angular/core";

@Pipe({
name: "toThousandPipe",
})
export class toThousandPipe implements PipeTransform {
transform(value: number) {
return this.toThousandNumber(value);
}

toThousandNumber(param: number) {
const paramStr = param.toString();
if (paramStr.length > 3) {
return paramStr.replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
return paramStr;
}
}

說明:

  1. 先輸入 @Pipe,便會自動引入元件,並在此方法裡面建立一個物件為 {name:'customPipeName}',那這邊我自定義為 toThousandPipe
  2. 要把這個 pipe 匯出(export)使用,並且用 PipeTransform 實作介面。
  3. 要先建立一個 transform(value)的方法,裡面的參數在建立時會自己帶出,裡面要把等等要實作的方法 return 出來給 transform 這個函式使用,才會把值輸出。
  4. 建立我要轉千分位的函式。
  5. 因為資料傳進來的是 number,所以我要先做一次轉型,為的是要判斷字串長度。
  6. 並用 replace 的陣列方法,替換成正則表達式,並於每三個中間加入逗號做區隔,變成千分位數的顯示方式,只要超過 3 個字串,也就是 1000 的時候,就會自行在千位數後面加上逗號。
  7. 若小於 3 個字串,則顯示原本的字串。

滿簡單確實用的小功能。

放入要使用的 module.ts 中並且在模板中引入

每次寫完 pipe 都很開心想直接用,但卻忘了引入在會使用到的 module 內,範例式引入在 app.module.ts,實際上要看專案引入。

最後記得要在模板上使用喔!

pipe.component.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<div class="p-3">
<h1 class="py-2 text-purple-500 tracking-wide">
使用 Pipe 成為共用管道轉成「千分位數」
</h1>
<p>當超過 1000 就加上逗號區隔,若沒有就顯示原本的數值</p>

<table class=" border-2 border-purple-700 w-full">
<thead class=" bg-purple-700 text-white">
<tr>
<th class="py-2 px-4 text-center">品項</th>
<th class="py-2 px-4 text-center">價格</th>
<th class="py-2 px-4 text-center">品項</th>
<th class="py-2 px-4 text-center">價格</th>
<th class="py-2 px-4 text-center">品項</th>
<th class="py-2 px-4 text-center">價格</th>
<th class="py-2 px-4 text-center">品項</th>
<th class="py-2 px-4 text-center">價格</th>
</tr>
</thead>
<tbody>
<tr>
<ng-container *ngFor="let item of data">
<td class="py-2 px-4 text-center border-purple-700 border-2 ">
{{item.name}}
</td>
<td class="px-4 py-2 text-center border-purple-700 border-2">
{{item.price | toThousandPipe}}
</td>
//這裡使用
</ng-container>
</tr>
</tbody>
</table>
</div>

Demo

連結:https://github.com/hsuchihting/angular_demo/blob/main/src/app/page/pipe/pipe.component.html

參考資料