【发布时间】:2019-06-27 16:09:41
【问题描述】:
我在 Angular 应用程序 (calendarComponent) 中有一个日历,它通过来自 mongodb 的 firebase 云函数获取其条目(通过名为 calendarService 的服务)。要创建一个新条目,我会弹出一个角度材质对话框(addEventComponent)。此对话框需要数据库中的一些数据才能工作。到目前为止,对话框组件从 calendarService 请求数据,每次我想添加一个条目时它都会发出一个新的 http 请求。除了有明显的延迟外,它可能会根据 Firebase 数据计划引发成本增加。 理想情况下,calendarComponent 会从 ngOnInit 上的 calendarService 请求数据,并根据请求将其传递给 addEventComponent,但这仅在单击新条目对话框时 http 请求完成时才有效。 我对 angular 和 rxjs 太缺乏经验,无法以一种不丑陋的方式解决这个问题。
我最初尝试的是这样的:
calendarComponent
内部requiredData: RequiredData[];
ngOnInit() {
this.calendarService.getRequiredData().subscribe(response => {
this.requiredData = response.data;
});
}
addNewEntry () {
const dialogData = this.requiredData;
const dialogRef = this.dialogModal.open(AddEventComponent, {
data: { requiredData: dialogData },
});
}
(CalendarService 只是返回一个 http.get() 请求,所以我没有在这里写代码。)
只要 http 请求不需要永远,它就可以很好地工作。作为一个临时解决方案,我像以前一样触发了 http 请求,但将响应保存在 calenderService 中并返回了一个可观察的。看起来像这样:
calendarComponent
内部ngOnInit() {
this.calendarService.getRequiredData();
}
在calendarService
中private requiredData$ = new Subject<RequiredData>();
requiredData: RequiredData[];
getRequiredData () {
this.http.get<{ _msg: string, reqData: RequiredData[] }>(API_URL)
.subscribe(response => {
this.requiredData = response.reqData;
this.requiredData$.next([...this.requiredData]);
});
}
getReqData () {
return this.requiredData$.asObservable();
}
我的问题发生在 AddEventComponent
requiredData: RequiredData[];
ngOnInit() {
this.calendarService.getReqData().subscribe(response => {
this.useTheRequiredData(response);
});
}
上面的代码不起作用,因为如果请求已经完成,订阅不会触发。所以我需要的是一种更智能的方法来执行此操作,或者是一个代码来检查可观察对象是否已经发出值,如果没有,则等待第一次发出,然后触发后续函数。有点像下面这样,但不那么粗糙和工作。
在AddEventComponent
里面requiredData: RequiredData[];
ngOnInit() {
if (this.calendarService.requiredData) {
this.useTheRequiredData(this.calendarService.requiredData);
} else {
this.calendarService.getReqData().subscribe(response => {
this.useTheRequiredData(response);
});
}
}
感谢每一个帮助。
似乎可行的是 (AddEventComponent)
this.calendarService.requiredData
? this.useTheRequiredData(this.calendarService.requiredData)
: this.calendarService.getReqData().pipe(
take(1),
tap(response => {
this.useTheRequiredData(response);
})
).subscribe();
主要让我感到困惑的是使用纯管道(模板中的角度过滤器管道,而不是 rxjs 管道),并没有意识到很长。
【问题讨论】:
标签: angular rxjs angular-material