有没有办法将不纯的管道转换为纯管道?

时间:2019-05-03 19:53:57

标签: angular angular-pipe

我是Angular 7的新手,但是我已经对AngularJS编程了几年了。我的问题基于以下事实:在管道中执行异步任务(不一定是ajax调用,它可以是另一个异步任务)时,必须将其声明为不纯。

根据Angular Docs

  

Angular在每个组件更改检测周期内执行一个不纯管道。每次击键或移动鼠标时,都会经常调用不纯管道。

这些调用很多,例如,如果您在50行的表或列表中使用同一管道,请尝试放置console.log,您会看到每个管道再次执行的次数非常多一遍又一遍。不纯管道中的ajax调用示例:

import {Pipe, PipeTransform} from '@angular/core';
import {AnyService} from '../services/any.service';

@Pipe({
  name: 'anyAjaxCall',
  pure: false
})
export class AnyAjaxCallPipe implements PipeTransform {

  private isDataCached = false;
  private cachedData: string = null;

  constructor(private anyService: AnyService) {
  }

  transform(value: any): string {

    if (!this.isDataCached) {
      this.isDataCached = true;

      this.anyService
        .read(value)
        .subscribe((response: any) => {
          this.cachedData = response.data.name;
        }, (err: any) => {
          this.isDataCached = false;
          console.error(err);
        });
    }

    return this.cachedData;
  }

}

了解了上述内容,一旦异步任务完成,是否可以将管道从不纯管道转换为纯管道?我知道有可能将异步操作的结果保存在变量中作为缓存并避免多次执行(例如上面的代码示例),但是我认为告诉Angular我已经执行了异步任务并且不想再次运行它会更好。 >

我不是专业人士,所以欢迎提出任何建议。

1 个答案:

答案 0 :(得分:1)

简短的回答:不,不可能将其从不纯转换为纯。但是,您的示例与official docs上给出的示例非常相似:

import { HttpClient }          from '@angular/common/http';
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'fetch',
  pure: false
})
export class FetchJsonPipe implements PipeTransform {
  private cachedData: any = null;
  private cachedUrl = '';

  constructor(private http: HttpClient) { }

  transform(url: string): any {
    if (url !== this.cachedUrl) {
      this.cachedData = null;
      this.cachedUrl = url;
      this.http.get(url).subscribe(result => this.cachedData = result);
    }

    return this.cachedData;
  }
}

但是,根据您的用例,我将该值移到服务中(在角度服务中为单例),并在整个应用程序中共享结果。稍后,在文档中谈论为什么不再使用管道it does say进行过滤或排序时:

  

您将放置在管道中并在应用程序之间共享的任何功能都可以写入过滤/排序服务中,并注入到组件中。

再次取决于您的用例,但我希望这会有所帮助。