Angular 2 有状态管道

示例

Angular 2提供了两种不同类型的管道-无状态管道和有状态管道。默认情况下,管道是无状态的。但是,我们可以通过将pure属性设置为来实现有状态管道false。如您在参数部分所看到的,您可以指定aname并声明管道是否应为纯管道,这意味着有状态或无状态。尽管数据流经一个不会记住任何内容的无状态管道(这是一个纯函数),可以通过有状态管道来管理和记住数据。有状态管道的一个很好的例子AsyncPipe是Angular 2提供的。

重要

请注意,大多数管道应属于无状态管道类别。由于性能原因,这一点很重要,因为Angular可以为变更检测器优化无状态管道。因此,请谨慎使用有状态管道。通常,与Angular 1.x中的过滤器相比,Angular 2中的管道优化具有重大的性能增强。在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 (typeofthis.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接口,以便一旦管道被破坏就可以清理。在上面的示例中,有必要清除间隔以避免内存泄漏。