有狀態的管道
Angular 2 提供兩種不同型別的管道 - 無狀態和有狀態。管道預設是無狀態的。但是,我們可以通過將 pure
屬性設定為 false
來實現有狀態管道。正如你在引數部分中看到的,你可以指定 name
並宣告管道是否應該是純的,意味著有狀態或無狀態。當資料流經無狀態管道(這是一個純函式)時,它不記得任何東西,資料可以通過有狀態管道進行管理和記憶。有狀態管道的一個很好的例子是由 Angular 2 提供的 AsyncPipe
。
重要
請注意,大多數管道應屬於無狀態管道類別。這對於效能原因很重要,因為 Angular 可以為變化檢測器優化無狀態管道。所以謹慎使用有狀態管道。通常,Angular 2 中管道的優化與 Angular 1.x 中的過濾器相比具有顯著的效能提升。在 Angular 1 中,即使資料根本沒有改變,摘要週期也必須重新執行所有過濾器。在 Angular 2 中,一旦計算出管道的值,變更檢測器就知道不再執行該管道,除非輸入發生變化。
實施有狀態管道
import {Pipe, PipeTransform, OnDestroy} from '@angular/core';
@Pipe({
name: 'countdown',
pure: false
})
export class CountdownPipe implements PipeTransform, OnDestroy {
private interval: any;
private remainingTime: number;
transform(value: number, interval: number = 1000): number {
if (!parseInt(value, 10)) {
return null;
}
if (typeof this.remainingTime !== 'number') {
this.remainingTime = parseInt(value, 10);
}
if (!this.interval) {
this.interval = setInterval(() => {
this.remainingTime--;
if (this.remainingTime <= 0) {
this.remainingTime = 0;
clearInterval(this.interval);
delete this.interval;
}
}, interval);
}
return this.remainingTime;
}
ngOnDestroy(): void {
if (this.interval) {
clearInterval(this.interval);
}
}
}
然後你可以照常使用管道:
{{ 1000 | countdown:50 }}
{{ 300 | countdown }}
重要的是你的管道也實現了 OnDestroy
介面,這樣你就可以在管道被破壞後進行清理。在上面的示例中,有必要清除間隔以避免記憶體洩漏。