2017-02-22 86 views
2

我试图从3个不同的REST端点获取数据。数据模型由主数据组成,并且具有高级数组和2(可能在将来更多)对象。我想根据每个高级对象中指定的REST端点将带有选项的数组注入到每个高级对象中。一切正常,并从Observable作为Object返回,除了附加选项外,它们都是Observable。从另一个可观察对象内部的可观察对象返回对象

简化数据:

{ 
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 
    }, 
    ... 
    ] 
} 

在我的数据模型,我没有选择[]数组,所以我手动注入它。服务:

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异步管道订阅观测。我怎样才能将我的选项追加到高级的实际数组而不是流?

编辑 - 解决方案

由于马丁的回答,解决的办法是拉平两个流,并将它们到底有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; 
    }) 
    }); 

回答

1

我没有测试,但我连接认为你可以如下的东西:

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; 
    }); 
    }) 
+0

这帮助我很多,我得到所有预期的选项,问题是,我想g将它们附加到整个对象 - 其中'.map((config)=> config.json()advanced)'直接映射到高级。 – Tina333

+0

@ Tina333啊,我明白了。然后它变得更复杂一点。我正在使用'forkJoin()'等待所有'this.http'完成,然后用它们的结果更新'configuration'。 – martin

+0

非常感谢,我设法解决了它。所以这就是我解释错了我想要的 - 将每个选项数组追加到每个高级对象,基于每个url(而不是整个Object,如我所解释的)。我设法通过在'observables.'上添加一个concatMap()来实现你的建议。我在问题中添加了修改后的代码。 – Tina333