我在从后端发出http请求时丢失了数据。我试图让一个plunker来展示我的问题,但我没有让它工作,配置有些问题?但是,只有必要的代码才能展示我的问题:Plunker
好吧,我试图用本地Json展示我的问题,但实际上我有一个实际的后端。检索单个英雄时,问题在于服务。这就是我丢失数据的地方。
Hero
类的一部分:
export class Hero {
private powers: Array<Power>;
constructor(public id: string, public name: string) {
this.powers = new Array<Power>();
}
}
一位英雄的Json示例:
{
"id":"randomString",
"name":"heroName",
"powers":[
{
"text":"power",
"value":"1"
}
]
}
在执行getById
方法时,我需要将传入的数据指定为新的英雄,然后将数组遗留给powers
,因为它在Hero
类中是私有的只能指定英雄的身份和姓名:
public getById(id: string) {
return this.http.get('/app/hero.json')
.map((res: Response) => res.json())
//without following line it gives self.context error:
.map(res => new Hero(res.id, res.name))
}
所以我失去了数据阵列和数组中的所有数据,因为每次我检索一个英雄时它都会创建一个新的Powers数组。当然,我想要Hero对象中的所有数据!
所以在这个示例app中我忽略了使用id,只是返回一个英雄。我注意到在打印到控制台时,在这个例子中完全忽略了powers
数组,但是在我的实际应用中它会创建一个新数组!顺便说一句,在我的实际应用程序中,我的方法看起来像这样:
getById(id: string) {
return this.http.get('someURL' + id)
//.map((res: Response) => {console.log('res', res);}); // <--- logs correct data including powers that is populated with data!
.map((res: Response) => res.json())
//unless this following line is added, it gives error "self.context...", BUT I lose data!
.map(hero => new hero(hero.id, hero.name));
}
我试图过滤英雄,但它不起作用!
//undefined
getById(id: string){
return this.http.get('/app/heroes.json')
.map(heroes => this.heroes.filter(hero => hero.id === id)[0]);
}
所以我真的不知道如何前进,如何获取存储在powers数组中的数据,而不仅仅是英雄的名字和id。
答案 0 :(得分:1)
您的Hero类有两个参数,id
和name
。由于您只传递了这两个参数,因此JSON上的powers
数组永远不会被使用。
您可以添加可选的powers
参数:
class Hero {
constructor(public id: string,
public name: string,
private powers: Power[] = []) {}
}
请注意语法:private powers: Power[] = []
。这使得powers
成为可选参数,其默认值为空数组。这与您使用this.powers = new Array<Power>();
完全一样,除非它允许您传入一组权力(如果它们已经存在)。
查看您的plunkr,唯一的问题是您已将Power
声明为类,这意味着您必须在每个项目上调用new Power()
在将JSON传递给构造函数之前,在JSON上的powers
数组中。如果权力本身实际上没有类方法,您可以将其更改为接口以保留类型,同时使实例化更容易:
interface Power {
text: string;
value: string;
}
在getById
函数中,您只需要添加powers参数:
public getById(id: string) {
return this.http.get('/app/hero.json')
.map((res: Response) => res.json())
.map(res => new Hero(res.id, res.name, res.powers))
}
如果确实需要Power
作为类,另一个选项是向专门用于服务器响应的Hero
类添加静态方法:
class Hero {
constructor(public id: string,
public name: string,
private powers: Power[] = []) {}
static initFromJSON(json): Hero {
let id = json.id;
let name = json.name;
let powers: Power[] = json.powers.map(power => new Power(power.text, power.value));
return new Hero(id, name, powers);
}
}
然后您可以将getById
功能设为:
public getById(id: string) {
return this.http.get('/app/hero.json')
.map((res: Response) => res.json())
.map(res => Hero.initFromJSON(res))
}
答案 1 :(得分:0)
上面的答案可以作为一个魅力,但一直在玩我的代码,我也想出了以下内容。因此,如果数组Power
在Hero
类中是私有的,那么这是另一种解决方案。
无需更改课程,因此保持不变:
export class Hero {
private powers: Array<Power>;
constructor(public id: string, public name: string) {
this.powers = new Array<Power>();
}
}
getById
方法与上面答案中的第二个方法相同:
public getById(id: string) {
return this.http.get('/app/hero.json')
.map((res: Response) => res.json())
.map(res => Hero.heroFromJSON(res))
}
将此静态方法添加到Hero
类:
static heroFromJSON(json) {
let hero = Object.create(Hero.prototype);
return Object.assign(hero, json, { powers: new Array<Power>(json.powers) })
}