我在将两个HTTP API响应映射到Angular 2中的模型时遇到问题。通过一个API调用,我得到这样的结果:
[{
"id": 410,
"name": "Test customdata test",
"layer": [79,94]
}, {
"id": 411,
"name": "Test customdata test2",
"layer": 79
}]
另一个请求可以给我这个
[{
"id": 94,
"name": "xy"
}, {
"id": 79,
"name": "abc"
}]
我的模型看起来像这样:
export class Dataset {
public id: number;
public name: string;
public layer: Layer[];
}
export class Layer {
public id: number;
public name: string;
}
我怎么知道将这个JSON映射到一个模型中。我需要嵌套HTTP请求才能获取所有数据吗?如果我这样做
this.Http.get('urltogetdataset').map(response => response.json() as Dataset[] )
我得到了我的数据集对象,但当然图层参数是一个数字数组。 有没有想法的人?谢谢!
答案 0 :(得分:0)
我希望你的意思是有两条独立的路线?
/api/datasets => gets you datasets
/api/layers => gets you layers
然后,您可以继续将响应映射到类:
http.get('/api/layers').map(response => {
return response.json().map(item => new Layer().deserialize(item));
});
我建议在类中实现某种反序列化:
export class Layer {
public id: number;
public name: string;
public deserialize(input){
this.id = input.id;
this.name = input.name;
}
}
修改强>
对于数据集,请执行以下操作:
http.get('/api/datasets').map(response => {
let dataset = response.json().map(item => {
let dataset = new Dataset().deserialize(item)
for(let layerId of item.layer){
dataset.addLayer(layerService.getLayerById(layerId);
}
return dataset;
});
});
这将要求数据集类具有addLayer
方法。
export class Dataset {
public id: number;
public name: string;
public layer: Layer[];
public deserialize(input){
this.id = input.id;
this.name = input.name;
}
public addLayer(layer){
this.layer.push(layer);
}
}
此外,您需要layerService
之类的内容来获取以前加载的图层ID。这是getLayerById
方法的一个示例:
public getLayerById(id){
for(let layer of this.layers){
if(layer.id === id) return layer;
}
}
答案 1 :(得分:0)
我认为您的API会返回每个资源的所有项目。如果不是,请告诉我。
所以,我建议你这个解决方案:
export class RESTDatasetLoader {
...
retrieveDataset(): Observable<Dataset[]> {
return Observable.of(this.jsonDataset) //<- remplace here by the call to datasets
.combineLatest(Observable.of(this.jsonLayer), //<- remplace here by the call to layers
(dataset, layers) => this.mapToDataset(dataset, layers)
)
}
/*
* with your question, we have the call to dataset resource so:
* retrieveDataset(): Observable<Dataset[]> {
* return this.Http.get('urltogetdataset')
* .combineLatest(Observable.of(this.jsonLayer), //<- We don't have this call in your question
* (dataset, layers) => this.mapToDataset(dataset, layers)
* )
* }
*/
private mapToDataset(dataset: DatasetDTO[], layers: LayerDTO[]): Dataset[] {
return dataset.map(data => {
const mappedLayers: Layer[] = this.mapLayers(data, layers)
return new Dataset(data.id, data.name, mappedLayers)
})
}
private mapLayers(dataset: DatasetDTO, layers: LayerDTO[]): Layer[] {
return dataset.layer
.map(layerId => {
const layer = layers.find(layer => layer.id === layerId)
return new Layer(layer.id, layer.name)
})
}
}
在您的代码中,您必须在模块的Providers中引用RESTDatasetLoader。并且,将它注入角度分量
要获得完整代码:https://stackblitz.com/edit/angular-eoqebo?file=app%2Fapp.component.ts
同意@Aluan Haddad的回复,更喜欢界面,它是DTO(数据传输对象)。
在此之后,您将响应映射到您自己的对象,因为如果API的响应发生更改,您只需在一个位置更改,而不是在代码中的任何位置更改。
也许,如果您在Dataset
响应中有一个图层,那么您的问题就会出错。它不是数组而只是数字。如果它不是错误,那么如果您可以就这一点与API团队进行交流,那么它最好总是具有相同的结构。