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

Is there a way to convert an impure pipe to a pure one?

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

根据Angular Docs

Angular executes an impure pipe during every component change detection cycle. An impure pipe is called often, as often as every keystroke or mouse-move.

这些调用很多,例如,如果您在 50 行的 table 或列表中使用相同的管道,请尝试放置一个 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 我已经执行了我的异步任务并且我没有执行'不想再 运行 了。

我不是前端方面的专家,所以欢迎任何建议。

简短回答:不,不可能将其从不纯转化为纯。但是,您的示例与 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;
  }
}

然而,对于它的价值,根据您的用例,我会将调用转移到服务中(在 angular 中服务是单例)并在整个应用程序中共享结果。稍后在文档中谈论为什么他们不再有过滤器或按管道排序 it does say:

Any capabilities that you would have put in a pipe and shared across the app can be written in a filtering/sorting service and injected into the component.

同样,这取决于您的用例,但我希望这对您有所帮助。