也许最好用一个例子来解释。
我有以下课程:
export class Foo {
bar: string;
doSomething() {
// whatever
}
}
以下提供者:
@Injectable()
export class FooProvider {
constructor(private http: HttpClient) {
}
getFoos(): Observable<Foo[]> {
return this.http.get<Foo[]>('/foos')
}
}
我期望在订阅Observable
时,数据将是Foo
个对象的实际数组。但令我惊讶的是,数组中的对象是简单的javascript对象,只有数据,没有方法(实际上当试图在其中任何一个中执行doSomething()
时会出现is not a function
错误。
我能够做到的唯一方法是通过这样的方式映射observable:
@Injectable()
export class FooProvider {
constructor(private http: HttpClient) {
}
getFoos(): Observable<Foo[]> {
return this.http.get<Foo[]>('/foos')
.map(foos => {
foos.map(foo => {
let f = new Foo();
Object.assign(f, foo);
return f;
};
});
}
}
问题是,我不想在每个提供商的每个方法中都这样做。看到转换的代码很简单,我猜我错过了一些东西,但是我无法在文档中找到它。
有人可以帮我吗?
答案 0 :(得分:1)
就像@toskv所说,你需要手动创建对象。虽然标记为重复的两个答案都可以解决OP问题,但我想添加这个答案,因为我通常会做一些不同的事情。
所有答案都使用Object.assign(f, foo);
将属性从普通对象复制到类实例。没关系,但就我而言我希望能够更好地控制应用中使用的属性名称。为什么?因此,如果api返回一个属性username
,但随后它被更改并且同一属性的名称为fullname
,我不想更新该应用的所有页面,其中该属性为被使用。
因此我通常会创建一些静态方法,如下所示:
export class Foo {
bar: string;
doSomething() {
// whatever
}
// Static method that creates the instance from
// a plain javascript object
public static fromObject(object: any): Foo {
let instance = new Foo();
if(!object) return instance;
// Here you can decide which name should each property have.
// If the API changes in the future, you would only need to
// modify a single line of code and that's it. You could also
// modify each property and give it a specific format if you want
instance.bar = object.bar;
// more properties ...
return instance;
}
// Static method that creates a list of instances from a list
// of plain javascript objects
public static fromJsonList(objectList: Array<any>): Array<Foo> {
let instances = new Array<Foo>();
if (!objectList || (objectList && objectList.length === 0)) return Foo;
objectList.forEach(object => instances.push(Foo.fromJson(object)));
return instances;
}
}
然后,我在服务中使用它:
getFoos(): Observable<Foo[]> {
return this.http.get<Foo[]>('/foos').map(response => Foo.fromJsonList(response));
}
通过这样做: