我对Angular刚起步(我使用的是最新版本的cli),并且肯定会有一种非常简单的方法来完成我正在尝试的事情(非常不好做),我们将不胜感激!
我们正在重建应用程序前端,此刻,我们的数据由以下端点/ cars提供,我们收到:
{
"cars": ["Fiesta","Toyota", "Fiat"]
}
每辆车都有一个端点,其中包含更多详细信息,因此/Fiesta
返回:
{
"Fiesta": [ ["model":"Sentra", "doors":4, "brand":"Fiesta"]
}
(为示例进行了简化)
我有一个car.service.ts
发出了get请求:
search(term: string) {
let apiURL = `${this.apiRoot}${term}`;
return this.http.get(apiURL)
}
然后我被卡住了...我们使用一个轮询系统,所以我们执行一个get请求以获取this.search("cars")
的汽车列表,然后对于每辆汽车,我们再次请求该特定汽车的详细信息。这需要每5-10分钟运行一次,以在添加或删除新车时保持更新。这是我在car.compontent.ts
中尝试过的:
doSearch(search: string) {
this.service.search(search).subscribe((
res => { this.cars = res;
for (let car of this.cars) {
this.service.search(car).subscribe((
result => { let newCar = {
show: true, car, result
}; this.loaded.push(newCar);
}))
}})
)};
并且像这样在html中显示;
<div *ngFor="let car of loaded">{{car.car}}
<div *ngFor="let result of car.result">{{result.model}} {{result.doors}}<div>
</div>
这显然是不正确的,而且可怕的是,当我每隔5分钟执行一次setInterval
来运行它时,html就会不断重复。如果首先清空doSearch
中的数组,我将得到所需的内容,但页面会闪烁并重建。我要做的就是获取汽车列表,然后为每辆汽车获取该汽车的详细信息列表,以便可以构建一个页面,同时显示汽车的标头和详细信息,并在轮询数据时进行更新。
有人能指出我正确的方向吗?非常感谢。
答案 0 :(得分:0)
显然民意测验糟透了。您应该使用websockets / socket.io(服务器会在数据更改时通知客户端)。但是,我确定这将需要您没有时间或意愿进行服务器更改。所以关于你的问题...
基本上,在您的服务中,您将创建一个返回Observable的方法,该方法发出所需的确切值。因此,当您订阅它时,您将获得所需的数据(或仅使用异步管道而不是分段)。
您的服务方法如下所示:
getCarDataIWant() {
let apiURL = `${this.apiRoot}${term}`;
return this.http.get(apiURL)
.pipe(
tap((cars) => { console.log('cars', cars) }),
mergeMap((cars) => { return this.http.get(apiURL + cars[0]) })
tap((firstCar) => { console.log('firstCar', firstCar) }),
// do your RxJS pipe transformations here
);
}
在管道部分内,您可以在其中转换数据。管道内的每一行都会转换数据,并将转换后的数据传递到下一行。我不会花时间为您编写整个内容,但这是您想要的基本方法。您将需要研究所需的RxJS运算符。点击,地图,mergeMap,switchMap都很受欢迎。您还需要一个运算符来处理迭代。
可观察到的RxJS基本上是流。流本质上是随时间推移而不是内存中的数组。因此,大多数JavaScript数组方法都是有效的RxJS运算符。
关于mergeMap的注释。其他大多数操作员都是不言自明的,但是这很棘手。基本上,this.http.get返回一个Observable(AKA流)。但是,您不希望下一行有一个流,而是想要从该流中发出的值,这就是mergeMap所提供的。
答案 1 :(得分:0)
如果我先在doSearch中清空数组,我会得到想要的内容,但页面会闪烁并重建。
您可以使用新数据重新分配阵列。为避免闪烁,应在trackBy
中使用ngFor
函数:
<div *ngFor="let car of loaded; trackBy: trackByCar">{{car.car}}</div>
类似
public trackByCar = (_, car) => car.id;