当它已经完成了角度数据的获取后,如何一一显示数据

时间:2020-04-07 06:52:38

标签: javascript angular typescript

HTML

<div nz-row *ngIf="tempThermometer | async as temp">
<div *ngFor="let data of temp;let i = index;" nz-col nzXs="24" nzSm="12" nzMd="12" nzXl="8" nzXXl="6">
<nz-spin nzTip="Loading..." [nzSize]="'large'" [nzSpinning]="data.spinning">
                            <div echarts [options]="chartOption[i]" [autoResize]="true" style="height: 270px;"></div>
                          </nz-spin>
    </div>
    </div>

TS

 tempLoading = false;
  tempThermometer = new BehaviorSubject<any>([]);

getRoomList() {
    this.tempLoading = true;
    this.subscription = this.global
      .getData(`/conditions/latest?length=${this.pageSize}`)
      .pipe(take(1))
      .subscribe((res: any) => {
        this.tempThermometer.next(Object.values(res['data'].map((obj: any) => {
          return {
            ...obj,
            spinning: true
          };
        })));

        this.tempLoading = false;
        this.lineChart(this.tempThermometer.value);
      });
  }
lineChart(params?: any) {
    const _this = this;
    const list: any = [];

    params.forEach((param: any) => {
      const url = encodeURIComponent(param.sensor);
      // List URL
      list.push(`/conditions?length=${this.length}&sensor=${url}`);
    });
    // Promise requests
    const promises = list.map(
      (url: any) =>
        new Promise(resolve => {
        this.subscription =  this.global.getData(url).pipe(take(1)).subscribe((res) => {
            resolve(res);
          }, (err: Error) => {
            return reject(err);
          });
        })
    );
    // Retrieve each data as per promise
    Promise.all(promises).then(results => {
      const dataRoom: any = [];

      results.map((result) => {
        const date: any = [], temperature: any = [], humidity: any = [], newRoomData: any = [];
        const param = result['data'];
        const roomData = orderBy(param, ['date'], ['asc']);
        const room = roomData.slice(-1)[0];
        const timeEnd = room.date.slice(0, 19);
        const timeStart = subHours(timeEnd, 7);
        const dataHour = roomData.filter((data: TemplogRecord) => {
          return !isBefore(data.date, timeStart) && !isAfter(data.date, timeEnd);
        });

        // console.log(roomData);

        const hash = Object.create(null);

        dataHour.forEach((data: any) => {
          const key = data.date.slice(0, 13);

          if (!hash[key]) {
            hash[key] = {
              sensor: data.sensor, temperature: data.temperature,
              humidity: data.humidity, date: key + ':00:00'
            };
            newRoomData.push(hash[key]);
          }
        });

        for (let x = 0; x < newRoomData.length; x++) {
          temperature.push(newRoomData[x].temperature);
          humidity.push(newRoomData[x].humidity);
          date.push(newRoomData[x].date);
        }

        dataRoom.push({
          date: date,
          humidity: humidity,
          temperature: temperature
        });
      });

      dataRoom.forEach((param: any, index: number) => {
        const option = {
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              animation: false
            },
            backgroundColor: 'rgba(245, 245, 245, 0.8)',
            borderWidth: 1,
            borderColor: '#ccc',
            padding: 10,
            textStyle: {
              color: '#000'
            },
            formatter: function (prm: any) {
              let rec = prm[0].name.slice(0, 10) + '<br/>' + prm[0].name.slice(11, 19) + '<br/>';

              for (let x = 0; x < prm.length; x++) {
                if (prm[x].axisIndex !== 1) {
                  rec += prm[x].marker + ' ' + prm[x].seriesName + ': '
                    + prm[x].data + _this.units['Celcius'] + '<br/>';
                } else {
                  rec += prm[x].marker + ' ' + prm[x].seriesName + ': '
                    + prm[x].data + '%' + '<br/>';
                }
              }
              return rec;
            }
          },
          ...this.echart.roomChart,
          dataZoom: [{
            type: 'inside',
            show: false,
            bottom: 0,
            width: '84%',
            xAxisIndex: [0, 1],
            zoomOnMouseWheel: false,
          },
          {
            type: 'slider',
            bottom: 0,
            show: false,
            width: '84%',
            xAxisIndex: [0, 1],
            zoomLock: false,
          }],
          xAxis: [{
            type: 'category',
            boundaryGap: false,
            scale: true,
            axisLine: {
              show: false
            },
            axisTick: {
              show: false
            },
            data: param.date.map((str: any) => {
              return format(str, 'YYYY-MM-DD hh:mm a');
            }),
            splitLine: {
              show: true,
              lineStyle: {
                color: 'rgba(182, 202, 227)'
              }
            },
            axisLabel: {
              show: true,
              interval: 0,
              rotate: 90,
              formatter: ((data: any) => {
                return (data).slice(11, 19);
              })
            }
          },
          {
            gridIndex: 1,
            show: false,
            scale: true,
            type: 'category',
            boundaryGap: false,
            axisLine: {
              show: false
            },
            data: param.date,
            axisTick: {
              show: false
            },
            splitLine: {
              show: true
            }
          }],
          series: [{
            name: 'Humidity',
            data: param.humidity,
            type: 'line',
            itemStyle: {
              color: 'rgba(0, 101, 144, 1)'
            },
            markPoint: {
              type: 'Pin',
              data: [
                {
                  type: 'max',
                  itemStyle: {
                    color: 'rgba(0, 101, 144)'
                  }
                },
                {
                  type: 'min',
                  itemStyle: {
                    color: 'rgb(110, 151, 204)'
                  }
                }
              ]
            },
            smooth: true,
            xAxisIndex: 1,
            yAxisIndex: 1
          },
          {
            name: 'Temperature',
            data: param.temperature,
            type: 'line',
            itemStyle: {
              color: 'rgba(255, 0, 0, 1)'
            },
            markPoint: {
              type: 'Pin',
              data: [
                {
                  type: 'max',
                  itemStyle: {
                    color: 'rgba(255, 5, 0)'
                  }
                },
                {
                  type: 'min',
                  itemStyle: {
                    color: 'rgb(255, 87, 86)'
                  }
                }
              ]
            },
            smooth: true
          },

          ]
        };
        this.chartOption.push(option);
        this.notScrolly = true;
        this.tempThermometer.value.filter((x: any) => params.map((y: any) => {
          if (y.id === x.id) {
            return y.spinning = false;
          }
        }));
      });
    });
  }

这里的问题是,加载时会先获取所有数据,然后再显示所有数据。 我要在这里做的是,当第一个已经获取的项目显示出来,而其他项目仍在获取数据时。

例如,有5个项目,分别是区域1,区域2,区域3,区域4和区域5。

当区域1已经完成数据获取时,它将显示它。而另一个仍在加载/提取中。

就像区域1已经完成获取,然后是区域3然后是区域2然后是5然后是4。

完成获取的人将自动显示。

2 个答案:

答案 0 :(得分:1)

我将以以下两种方式之一来解决这个问题。都不涉及承诺。

我不会尝试使用您的代码示例,因为它太大了,相反,我将专注于您问题的核心-运行一系列可观察对象并在返回结果时对其进行处理。

1。合并观察值

RxJS merge函数将同时运行多个可观察对象,并立即使用各个值调用您的订阅回调。

const observables: Observable<any>[] = this.getObservables();
merge(...observables).subscribe(result => {
  // individual results are logged here as soon as the observable returns them
  console.log(result);
}, err => {
  // empty error callback. 
  // This is here to allow us to add the complete callback
}, () => {
  console.log('complete');
});

专业版:在订阅中易于处理结果

缺点:必须在完整的回调中运行完整的代码

2。在管道中处理结果

您可以在forkJoin中并行运行可观察对象。仅在最终可观察项完成时才调用订阅,但是您可以在各个tap运算符中处理结果。

const observables: Observable<any>[] = this.getObservables()
  .map(x => x.pipe(
    // tap is run as soon as the observable is returned
    tap(result => console.log(result))
  ));
forkJoin(observables).subscribe(result => {
  console.log('complete');
});

专业版:在订阅中进行简单的完整处理

Con 处理单个tap运算符中的结果可能会有些混乱

结论

这两种方法都相当等效。我可能更喜欢forkJoin方法,但是我想通过举第二个例子来演示RxJS的功能和灵活性。

演示:https://stackblitz.com/edit/angular-7rrmtn

该演示设置了5个可观察对象,每个观察对象具有不同的延迟。可观察值在返回结果时进行处理,并且它们在完成时都记录下来。

如您所见,它们在功能上是等效的。

答案 1 :(得分:0)

尝试添加更改检测策略 并在使用第一个数据点更新变量后立即运行 detectChanges 函数