javascript - Hvordan bruke HTTP-kall i ren pipe i Angular 5
Jeg lager et rør for å konvertere en valutaverdi til en annen. Jeg gjør et HTTP-kall for å konvertere verdien.
@Pipe({
name: "currencyConverter"
})
export class CurrencyConverterPipe implements PipeTransform {
transform(value: number, currencyPair: string): number {
let sourceCurrency = currencyPair.split(":")[0];
let destinationCurrency = currencyPair.split(":")[1];
this.currencyConverterService.convert(sourceCurrency, destinationCurrency).subscribe(successData => {
return successData['fiatValue'] * value;
}, errorData => {
console.error(errorData);
})
}
}
I HTML
<p> {{ value | currencyConverter:'BTC:USD'}}</p>
Jeg klarer ikke å se noen verdi i UI. Når jeg gjør røret mitt impure, da fungerer det, men det gjør mange HTTP-anrop til serveren. Er det noen måte å gjøre HTTP-anrop uten å bruke pure: false i røret
Svar #1
Dette røret er ikke rent med vilje.
For å unngå å forårsake flere forespørsler, bør det returnere samme observable som ikke vil gjøre ytterligere forespørsler før input endres, noe som ligner på:
@Pipe({
name: "currencyConverter",
pure: false
})
export class CurrencyConverterPipe {
private sourceCurrency;
private destinationCurrency;
private valueSubject = new Subject();
private value$ = this.valueSubject.asObservable().distinctUntilChanged()
.switchMap(value => {
return this.currencyConverter
.convert(sourceCurrency, destinationCurrency))
.map((data) => data * value);
});
constructor(private currencyConverter: ...) {}
transform(value: number, currencyPair: string): number {
this.sourceCurrency = currencyPair.split(":")[0];
this.destinationCurrency = currencyPair.split(":")[1];
this.valueSubject.next(value);
return this.value$;
}
}
Siden det er ment å brukes bare i forbindelse med async-rør, gir det mening å slå dem sammen og utvide AsyncPipe:
@Pipe({
name: "currencyConverterAsync",
pure: false
})
export class CurrencyConverterPipe extends AsyncPipe {
private sourceCurrency;
private destinationCurrency;
private valueSubject = new Subject();
private value$ = this.valueSubject.asObservable().distinctUntilChanged()
.switchMap(value => {
return this.currencyConverter
.convert(sourceCurrency, destinationCurrency))
.map((data) => data * value);
});
constructor(cdRef: ChangeDetectorRef, private currencyConverter: ...) {
super(cdRef);
}
transform(value: number, currencyPair: string): number {
this.sourceCurrency = currencyPair.split(":")[0];
this.destinationCurrency = currencyPair.split(":")[1];
this.valueSubject.next(value);
return super.transform(this.value$);
}
}
