Angular中的自定义管道不适用于每个元素-仅显示在for循环中的最后一个元素上



我正试图在Angular中创建我的第一个自定义管道。我有一个问题似乎无法解决。我有一个for循环,然后应用我的自定义管道来执行websocket调用,该调用应该显示许多元素的数据。但它只给了我一个可以在模板中观察到的元素,它是最后一个元素。所以我猜每次循环时它都会被覆盖。有人能帮我理解我在这里做错了什么吗:

这是我的自定义管道ts文件:

import { Pipe, PipeTransform } from '@angular/core';
import { map } from 'rxjs/operators';
import { Observable, Subject, of } from "rxjs";
import { BinanceWsService } from 'src/app/shared/services/binance-ws.service';
@Pipe({
name: 'pricePipe',
pure: false
})
export class PricePipe implements PipeTransform {
public price!: Subject<string>;
pricex!: Observable<string>;
constructor(
public binanceWsService: BinanceWsService
) {

}
transform(value: string, ...args: any[]): any {
return this.price(value);
}
price(symbol: string): Observable<string> {
const URL = `wss://fstream.binance.com/ws/${symbol}usdt@markPrice`
this.price = <Subject<string>>this.binanceWsService
.connect(URL)
.pipe(map((response: MessageEvent): string => {
let data = JSON.parse(response.data);
return data.p;
}
));
this.price.subscribe(msg => {
console.log(symbol + ': ' + msg)
this.pricex = of(msg);
})
return this.pricex;
}
}

这就是我尝试在for循环中访问它的方式:

{{ c.symbol | pricePipe | async | number}}

调用API对管道来说不是一个好用:https://angular.io/guide/pipes

使用管道转换字符串、货币金额、日期和其他显示数据。管道是简单的功能…

更好的方法是在显示之前使用rxjs来聚合数据。

在您的组件TS:

let symbols$ = getSymbolsFromService();
let pricedSymbols$ = symbols$.pipe(
map((symbols) =>
symbols.map((symbol) =>
getPriceFromBinance(symbol).pipe(map((price) => ({ symbol, price })))
)
),
mergeMap((pricedSymbols$) => forkJoin(pricedSymbols$))
);
  • 使用普通JS数组map为列表中的每个符号调用价格服务
  • 将价格结果与匹配符号组合
  • 使用mergeMapforkJoin将项目组合回单个对象,以便由pricedSymbols$发射

在您的模板中:

<div *ngFor=“let s of pricedSymbols$ | async”>
{{ s.symbol }}
{{ s.price }}
</div>

Stacklitz(检查控制台选项卡以获取输出(:https://stackblitz.com/edit/rxjs-dqymgd

最新更新