在工作上有一個需要轉千分位的需求,做個紀錄,專案使用 Angular 開發。
需求
規格書文件中提到以下需求:
- 有一筆資料有字串有數字,如下:
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, }, ];
|
- 當超過 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; } }
|
說明:
- 先輸入 @Pipe,便會自動引入元件,並在此方法裡面建立一個物件為
{name:'customPipeName}'
,那這邊我自定義為 toThousandPipe
。
- 要把這個 pipe 匯出(export)使用,並且用
PipeTransform
實作介面。
- 要先建立一個
transform(value)
的方法,裡面的參數在建立時會自己帶出,裡面要把等等要實作的方法 return 出來給 transform
這個函式使用,才會把值輸出。
- 建立我要轉千分位的函式。
- 因為資料傳進來的是 number,所以我要先做一次轉型,為的是要判斷字串長度。
- 並用 replace 的陣列方法,替換成正則表達式,並於每三個中間加入逗號做區隔,變成千分位數的顯示方式,只要超過 3 個字串,也就是 1000 的時候,就會自行在千位數後面加上逗號。
- 若小於 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
參考資料