有没有办法将不纯管道转换为纯管道?
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.
同样,这取决于您的用例,但我希望这对您有所帮助。
我是 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.
同样,这取决于您的用例,但我希望这对您有所帮助。