Angular 有没有办法把不纯净的管子换成纯净的?

Angular 有没有办法把不纯净的管子换成纯净的?,angular,angular-pipe,Angular,Angular Pipe,我是Angular7的新手,但我已经为AngularJS编程了几年了。我的问题是基于这样一个事实:当在管道中执行异步任务时(不一定是ajax调用,它可能是另一个异步任务),必须声明它不纯净 根据: Angular在每个组件更改检测循环期间执行不纯净管道。不纯净的管道经常被调用,就像每次击键或鼠标移动一样频繁 这些调用很多,例如,如果在50行的表或列表中使用相同的管道,请尝试放置console.log,您将看到每个管道反复执行的次数非常多。不纯管道中的ajax调用示例: import {Pipe,

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

根据:

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我已经执行了异步任务,我不想再运行它,这样性能会更好


我不擅长前端的东西,所以欢迎任何建议

简短回答:不,不可能把它从不纯净变成纯净。但是,您的示例与上给出的示例非常相似:

然而,根据您的用例,我会将该调用移动到服务中(在angular services中为单例),并在整个应用程序中共享结果。稍后在文档中,当谈到为什么不再有过滤器或order by pipe时:

任何你本应该放在管道中并在整个应用程序中共享的功能都可以写入过滤/排序服务并注入到组件中

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

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;
  }
}