所以,我是RxJS的新手,正在玩Angular 5,想知道如何完成以下任务:
让我们有一个表格。当页面加载时,我们需要3个select来填充来自服务器的数据,所以我们有3个Observable来完成这个。
现在,我们还有一个可观察到的路径参数更改时(在这种情况下,我们必须获取请求的记录并填充表格):
// These 3 guys will get the required data for each select
this.countryService.getAll().subscribe(countries => {
this.countries = countries;
});
this.categoryService.getAll().subscribe(categories => {
this.categories = categories;
});
this.sectorService.getAll().subscribe(sectors => {
this.sectors = sectors;
});
// And this is for the change in url
this.route.paramMap.subscribe(params => {
this.formDisabled = true;
const id = params.get('id');
// We get the resource based on the id param
this.service.get(id).subscribe(contact => {
this.contact = contact;
this.form.reset(this.contact);
this.formDisabled = false;
}
});
现在,我需要this.service.get(id).subscribe()
的回调才能在已经填充了3个选项后执行,即当他们各自的回调已经完成时,否则我们可能最终会尝试使用表单进行处理#39} ;没有完全建成。我希望它继续请求资源与其他3个请求并行,但只有在其他3个请求完成后才执行回调(用它重置表单)。
答案 0 :(得分:2)
如果您尝试布置要实现的 的步骤,而不是想要实现的 ,则通常会有所帮助。这会让你想到一个更多的反应性"方式。
获得3个下拉列表。这可以并行完成
检索路线参数
做其余的事情:
指定联系人的值。
重置表单
重新填写表格
布置完步骤后,将它们编码为可观察的步骤将非常简单:
//Step 1: Call the dropdownsService in parallel
Observable.forkJoin([
this.countryService.getAll(),
this.categoryService.getAll(),
this.sectorService.getAll()
])
.switchMap(([countries, categories, sectors]) => {
//Assign the dropdown values
this.countries = countries;
this.categories = categories;
this.sectors = sectors;
//Step 2: Retrieve the route params
return this.route.paramMap;
})
.switchMap(({id}) => {
//disable the form
this.formDisabled = true;
//step 3: Call the service to get contact info
return this.service.get(id)
})
.subscribe(contact => {
//Do the rest
this.contact = contact;
this.form.reset(this.contact);
this.formDisabled = false;
});
PS :我使用对象和数组解构来获得更简洁和可读的代码。
如果您想将this.service.get
与[{1}}服务并行呼叫,请将它们放在同一个dropdown
:
Observable.forkJoin
如果您想收听任何组合在一起的可观察对象的更改,无论谁首先发出,请使用Observable.forkJoin([
this.countryService.getAll(),
this.categoryService.getAll(),
this.sectorService.getAll(),
this.route.paramMap.switchMap(({id}) => {
this.formDisabled = true;
return this.service.get(id);
})
])
.subscribe(([countries, categories, sectors, contact]) => {
//Assign the dropdown values
this.countries = countries;
this.categories = categories;
this.sectors = sectors;
//Do the rest
this.contact = contact;
this.form.reset(this.contact);
this.formDisabled = false;
})
:
combineLatest()