使用Angular 5轮询端点并合并收到的数据

时间:2018-08-02 19:29:40

标签: angular typescript angular5

我对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中的数组,我将得到所需的内容,但页面会闪烁并重建。我要做的就是获取汽车列表,然后为每辆汽车获取该汽车的详细信息列表,以便可以构建一个页面,同时显示汽车的标头和详细信息,并在轮询数据时进行更新。

有人能指出我正确的方向吗?非常感谢。

2 个答案:

答案 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;