有状态的管道
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
接口,这样你就可以在管道被破坏后进行清理。在上面的示例中,有必要清除间隔以避免内存泄漏。