Return 来自另一个可观察对象内的可观察对象
Return object from observable inside another observable
我尝试从 3 个不同的 REST 端点获取数据。数据模型由主要数据组成,并具有带有 2 个(将来可能更多)对象的高级数组。我想根据每个高级对象中指定的 REST 端点,将带有选项的数组注入到每个高级对象中。一切正常,并作为对象从 Observable 返回,除了作为 Observables 出现的附加选项。
简化数据:
{
simple: {
param: "searchQuery",
},
advanced: [
{
param: "food",
optionsModel: {
url: "http://address.com/food",
}
},
{
param: "drinks",
optionsModel: {
url: "http://address.com/drinks",
}
}
]
}
食物和饮料具有相同的结构,由具有名称和 ID 的对象组成:
{
data: [
{
name: "DR1",
id: 1
},
{
name: "DR2",
id: 1
},
...
]
}
在我的数据模型中我没有 options[] 数组,所以我手动注入它。服务:
searchConfiguration$: Observable<SearchConfiguration> = this.http
.get(this._configURL)
.map((config) => {
let configuration = config.json();
let advancedArray = configuration.advanced;
if(advancedArray) {
advancedArray.forEach(advanced => {
advanced.options = [];
advanced.options = this.http.get(advanced.optionsModel.url)
.map((r: Response) => r.json().data
})
}
return configuration;
})
父组件:
getSearchConfig() {
this.searchConfiguration$ = this._bundlesService.searchConfiguration$;
}
然后我在 html 中有异步管道来订阅 Observable。如何让我的选项作为实际数组而不是流附加到高级?
编辑 - 解决方案
感谢 martin 的回答,解决方案是将两个流展平并在最后用 forkJoin()
连接它们
searchConfiguration$: Observable<SearchConfiguration> = this.http
.get(this._configURL)
.map((config) => config.json())
.concatMap((configuration) => {
let observables = configuration.advanced.map((advanced) => {
return this.http.get(advanced.optionsModel.url)
.map((r: Response) => r.json().data)
.concatMap((options) => advanced.options = options)
});
return Observable.forkJoin(observables, (...options) => {
return configuration;
})
});
我没有测试它,但我想你可以做如下的事情:
searchConfiguration$: Observable<SearchConfiguration> = this.http
.get(this._configURL)
.map((config) => config.json())
.concatMap(configuration => {
var observables = configuration.advanced.map(advanced => {
return this.http.get(advanced.optionsModel.url)
.map((r: Response) => r.json().data);
});
return Observable.forkJoin(observables, (...options) => {
configuration.options = options;
return configuration;
});
})
我尝试从 3 个不同的 REST 端点获取数据。数据模型由主要数据组成,并具有带有 2 个(将来可能更多)对象的高级数组。我想根据每个高级对象中指定的 REST 端点,将带有选项的数组注入到每个高级对象中。一切正常,并作为对象从 Observable 返回,除了作为 Observables 出现的附加选项。
简化数据:
{
simple: {
param: "searchQuery",
},
advanced: [
{
param: "food",
optionsModel: {
url: "http://address.com/food",
}
},
{
param: "drinks",
optionsModel: {
url: "http://address.com/drinks",
}
}
]
}
食物和饮料具有相同的结构,由具有名称和 ID 的对象组成:
{
data: [
{
name: "DR1",
id: 1
},
{
name: "DR2",
id: 1
},
...
]
}
在我的数据模型中我没有 options[] 数组,所以我手动注入它。服务:
searchConfiguration$: Observable<SearchConfiguration> = this.http
.get(this._configURL)
.map((config) => {
let configuration = config.json();
let advancedArray = configuration.advanced;
if(advancedArray) {
advancedArray.forEach(advanced => {
advanced.options = [];
advanced.options = this.http.get(advanced.optionsModel.url)
.map((r: Response) => r.json().data
})
}
return configuration;
})
父组件:
getSearchConfig() {
this.searchConfiguration$ = this._bundlesService.searchConfiguration$;
}
然后我在 html 中有异步管道来订阅 Observable。如何让我的选项作为实际数组而不是流附加到高级?
编辑 - 解决方案
感谢 martin 的回答,解决方案是将两个流展平并在最后用 forkJoin()
连接它们 searchConfiguration$: Observable<SearchConfiguration> = this.http
.get(this._configURL)
.map((config) => config.json())
.concatMap((configuration) => {
let observables = configuration.advanced.map((advanced) => {
return this.http.get(advanced.optionsModel.url)
.map((r: Response) => r.json().data)
.concatMap((options) => advanced.options = options)
});
return Observable.forkJoin(observables, (...options) => {
return configuration;
})
});
我没有测试它,但我想你可以做如下的事情:
searchConfiguration$: Observable<SearchConfiguration> = this.http
.get(this._configURL)
.map((config) => config.json())
.concatMap(configuration => {
var observables = configuration.advanced.map(advanced => {
return this.http.get(advanced.optionsModel.url)
.map((r: Response) => r.json().data);
});
return Observable.forkJoin(observables, (...options) => {
configuration.options = options;
return configuration;
});
})