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

Relaterte artikler