定義
管道用于在模板中轉換顯示的內容
案例
@Pipe({
name : 'addHero'
})
export class AddHeroPipe implements PipeTransform{
transform(pre : string) {
return pre + ' is a Hero';
}
}
詳解
1. 使用@Pipe注解
通常情況下我們只需要用到name屬性,對該自定義管道命名即可。在源碼定義上Pipe注解還有另一個可選屬性pure,默認為true,它定義了管道的檢測更新策略。
export interface Pipe {
name: string;
pure?: boolean;
}
什么意思呢?首先我們應當知道管道作為值的預處理,它可以極大地消耗應用運行速度。例如在一個ngFor中,每個值都被管道接管,如果它過于繁重,那么你的應用很可能像蝸牛一樣讓你著急。所以我們實現的transform應當保證足夠輕快。這是我們能做出的努力。那么Angular方面為我們做了哪些努力呢?正是這所謂的純管道。
我們爬一個官網的例子:
<div *ngFor="let hero of (heroes | flyingHeroes)">
{{hero.name}}
</div>
這個場景需要從一堆英雄中過濾一部分會飛的英雄,我們實現之后看起來很妥當。
那么我們來額外添加一個會飛的英雄,
heroes.push(flyingHero);
此時將發現視圖并沒有更新,對的,純管道為了更快,對于所有非純變更的值放棄更新檢測。所謂純變更,指原型變量(String、Number等)值變更或引用型變量(Array、Object等)引用變更。
我們的英雄們大本營(heroes的引用地址)并沒有搬走,它只是接納了一些新英雄。所以不足以來個大搜查。
如果我們強制改變引用:
heroes = heroes.concat(flyingHero)
是的,視圖更新了。
對于非純管道我們需要慎重,Angular會在每個組件的變更檢測周期中執行非純管道,而且可能會超乎你意料的頻繁
2. 實現PipeTransform接口
自定義管道必須實現PipeTransform接口,它在源碼中如下定義:
export interface PipeTransform {
transform(value: any, ...args: any[]): any;
}
管道的概念可以理解為值的流向,例如日期值流經DatePipe可以被處理為適合閱讀的格式。自定義管道正是為了定制這個處理方式。
當我們實現PipeTransform
的transform
方法,流入管道的原值作為第一個參數,其它過濾條件作為第二個參數(不定參)被我們獲取
摘取官網一個案例加以說明:
<p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </p>
其中birthday
為未經處理的原值,它被date
管道處理,附加的條件使用:
分隔并允許多個,此處只有一個參數"MM/dd/yy"
,那么在transform
中,
value
為birthday
原值,第二個參數我們將獲取到字符串"MM/dd/yy"
此時我們經過一系列處理,返回需要流出的值即可。