我正在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;
});
})
);
});
有没有更好的方法(主要是在性能和代码质量方面)?
答案 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]
}));
}
关于解析器,对我来说这似乎是一个好主意。