Pipe 是用在 Interpolation 或是 Property Binding 時,幫我們做資料格式的轉換,比方說我們要將字串轉成全大寫,可以用內建的 method toUpperCase()
。
// homepage.component.ts
constructor() {
this.name = 'Henry';
this.name = this.name.toUpperCase();
}
// homepage.component.html
<p> My name is {{ name }}.</p>
name 就會以全大寫的方式顯示。
但是 Angular 有更方便的 Pipe 可以使用,語法也很簡單,以上面的轉換大寫為例,使用 Pipe 的話,我們只需要這樣寫:
// homepage.component.ts
name = 'Henry';
// homepage.component.html
<p> My name is {{ name | uppercase }}.</p>
就會像上面一樣把字轉換成全大寫。
這個 Pipe 呢,其實在 Linux 系統下也很常用到,我想最常用的就是 grep
了。
下面的ls
就是列出當前目錄有哪些檔案,然後透過 Linux的 Pipe,將 ls
的結果丟給 grep
做處理,grep
會用 regular expression (正規表達式) 來過濾掉不相符的字串。
這邊我們設定的 regular expression 就是 .json
,所以 ls | grep .json
,就會把檔名中沒有 .json
的檔案過濾掉,只列出包含 .json
的檔案。這跟 Angular 的 Pipe 原理是一樣的。
當然也可以這樣使用,我有一個文字檔,放了一些單字,我一樣可以使用 grep
,來篩選單字,下面的例子就是用 cat
顯示檔案,並且分別輸出只包含 ap
以及 ab
的單字。
以上是一點小補充。
其他還有像 DatePipe、PercentPipe、CurrencyPipe 等內建的 Pipe:
這邊初始日期的地方雖然填 8,但實際上是設定九月,Mouth 的設定範圍是 0 ~ 11 ,0 代表一月,11代表12月,我也覺得很奇怪。
// homepage.component.ts
holiday = new Date(2019, 8, 28);
// homepage.component.html
<p> Today is {{ holiday | date }} </p>
預設會輸出這樣的格式 :
Pipe 也可以加上參數,參數用:
分隔。比方說我們想調整顯示格式跟時區,第一個參數我放時間格式 "MM/dd hh:mm:ss"
,第二個參數我放時區"+0900"
,結果如下:
// homepage.component.html
<p> Today is {{ holiday | date:"MM/dd hh:mm:ss":"+0900" }} </p>
或是可以使用 Angular 定義好的一些格式 long、medium、short等等。在Angular官方手冊都可以查到。下面是使用預定義格式 long
的結果:
// homepage.component.html
<p> Today is {{ holiday | date:"long":"+0500" }} </p>
並且 Pipe可以串聯使用,下面一併示範在 Property Binding 使用
CurrencyPipe,以及串接 Pipe,其實就只是單純用 |
繼續串聯下一個 Pipe指令:
// homepage.component.ts
price = 87.735;
// homepage.component.html
<input type="submit" [value]="price | currency:'CAD'| lowercase">
結果如下:
下指令建立一個 Pipe:
ng generate pipe <pipe name>
Pipe 同樣有 alias,所以也可以這樣下:
ng g p <pipe name>
就算建立時忘記打 pipe 的名字,Anglar 也會很貼心的問我們要怎麼命名:
我這邊用凱薩加密法示範,所以我命名為 Caesar
。
Angular 會幫我們建立兩個檔案,並修改 app.module.ts
,將CaesarPipe
放進 @NgModule
的 declarations
,這部分與建立 Component
類似。
接下來切換到 caesar.pipe.ts
,在 transform 填入要傳入的參數,以及回傳值的型別,還有 pipe 要如何轉換這筆資料。
第一個參數必須放你傳入要處理的資料,也就是 {{plainText | caesar:10}}
的 plainText。
plaintext
是我輸入的明文,offset
是傳入的偏移量,這邊是將每個字轉成 ascii code,加上偏移量再與 26 取模數,最後再轉回字串。
程式碼如下: (code真醜
// caesar.pipe.ts
transform(plaintext: string, offset: number): string {
let cipherText = '';
for (const char of plaintext) {
const charASCII = char.charCodeAt(0);
if (char >= 'a' && char <= 'z') {
let cipherchar = (charASCII - 'a'.charCodeAt(0) + offset);
while (cipherchar < 0) { cipherchar += 26; }
cipherText += String.fromCharCode(cipherchar % 26 + 'a'.charCodeAt(0));
} else if (char >= 'A' && char <= 'Z') {
let cipherchar = (charASCII - 'A'.charCodeAt(0) + offset);
while (cipherchar < 0) { cipherchar += 26; }
cipherText += String.fromCharCode(cipherchar % 26 + 'A'.charCodeAt(0));
}
}
return cipherText;
}
如此一來就能使用一個簡單的凱薩加密法 Pipe了:
// homepage.component.html
<p> Plaintext :{{plainText}}, ciphertext :{{plainText | caesar:-10}}</p>
<p> Plaintext :{{plainText}}, ciphertext :{{plainText | caesar:50}}</p>
<p> Plaintext :{{plainText}}, ciphertext :{{plainText | caesar:100}}</p>