链接依赖HTTP GET请求的最佳方式

时间:2018-01-11 14:00:39

标签: typescript rxjs angular5 angular-router

我正在Angular编写一个应用程序(当前v5.1.1),我对以下场景有几个问题: 我有一个数据表中显示的医生列表。当用户点击任何行时,我将所选医生的详细信息保存在可注射服务中,然后将(使用角度路由器)重定向到新组件(页面)以显示更多详细信息。这些详细信息包括个人详细信息,办公地点 - 可超过1个 - 以及每个办公地点的工作时间。

我不拥有后端服务,所以我无法通过一次调用创建服务来返回所有结果。有一项服务通过提供医生的身份证返回所有办公地点,还有另一项服务,通过提供医生的身份证和办公室的身份证,返回每个地点的工作时间。

我想要实现的是在我拥有服务调用返回的所有数据之后呈现新组件(页面),而不是异步显示数据,例如个人详细信息首先出现,因为它们在内存中或办公室位置一个接一个地出现。因此我决定使用路由器解析方法来实现这一点。 这是实现我想要的最佳做法吗?

现在,为了检索新组件所需的数据,我使用了RxJS运算符的组合,并设法使用resolve方法中的以下代码获得所需的结果:

this.doctorDetails = this.doctorDetailsService.getDetails();
this.doctorId = this.doctorDetails.uniqueCode;

return  this.doctorsService.getofficeLocations(this.doctorId)
.mergeMap((results: any[]) => {
        return Observable.forkJoin(
            results.map((result: any) => {
                return Observable.forkJoin(
                    Observable.of(result),
                    this.doctorsService.getofficeHours(this.doctorId, result.officeId)
                ).map((data: any[]) => {
                    const officeDetails = data[0];
                    const officeHours = data[1];
                    officeDetails.officeHours = officeHours;
                    return officeDetails;
                });

            })
        );
});

有没有更好的方法(主要是在性能和​​代码质量方面)?

1 个答案:

答案 0 :(得分:0)

我认为,出于不同的原因,编写所有代码会更好。

原因1
一般来说,尤其是在使用Rxjs时,尽量避免副作用。尽可能多地接受函数式编程。

原因2
这里没有必要使用forkJoin

return Observable.forkJoin(
    Observable.of(result),
    this.doctorsService.getofficeHours(this.doctorId, result.officeId)
).map(...)

为了避免出现这种“错误”,你应该总是问自己,如果你正在提取完全相同的值,你是否需要将值包装到一个observable中。

原因3
没有人想读...不可读的代码。尝试将代码拆分为较小的函数(这将帮助您阅读自己的代码,但也可以对其进行测试)。

<强>提案:

public getDetailsAndHours(doctorId: string) {
  return this.doctorsService
    .getofficeLocations(doctorId)
    .switchMap((results: any[]) => this.getDetailsAndHoursForAll(results));
}

private getDetailsAndHoursForAll(results: any[], doctorId: string) {
  return Observable.forkJoin(
    ...results.map(result =>
      this.getDetailsAndHoursForADoctorAndService(
        doctorId,
        result.officeId
      )
    )
  )
}

private getDetailsAndHoursForADoctorAndService(doctorId: string, officeId: string) {
  return this.doctorsService
    .getofficeHours(doctorId, officeId)
    .map(officeDetailsAndHours => ({
      ...officeDetailsAndHours[0],
      officeHours: officeDetailsAndHours[1]
    }));
}

关于解析器,对我来说这似乎是一个好主意。