问题描述
我说我有
class Foo {
bar: string;
public doSomething() {}
}
在我的服务中,我从服务器上获取了这些信息:
In my service I'm getting array of those from a server:
this.http.get<Foo[]>(...)
这有效,我得到了所有期望值.但是,当我拿到我获得的对象之一并尝试在其上调用doSomething()时,我收到一条错误消息,指出foo(类型为Foo)没有方法doSomething().
This works, I'm getting all the expected values. BUT when I take one of the objects I got and try to invoke doSomething() on it, I get an error saying that foo (which is of type Foo) doesn't have method doSomething().
看来,尽管http.get正确地解析了JSON并分配了对象的所有属性,但它并没有为它们设置适当的原型而烦恼,因此从本质上讲,它们只是Foos,缺少所有方法的
It appears that while http.get correctly parsed JSON and assigned all the properties of my objects, it didn't bother with setting up proper prototypes for them, so essentially they are Foos in name only, they are missing all the methods of Foo.
那是正常现象还是我做错了什么?谢谢.
Is that normal or am I doing something wrong?Thank you.
推荐答案
有效.最后,您只是解析JSON,而解析JSON的结果只是普通的JavaScript对象,而不是自定义类. this.http.get<Foo[]>
只是对编译器的提示,但泛型参数实际上并没有执行任何操作.它不会将一个对象转换为另一个对象,也不给它们提供类型.
Effectively. In the end, you're just parsing JSON, and the result of parsing JSON are just plain JavaScript objects, never custom classes. this.http.get<Foo[]>
is just a hint for the compiler, but the generic parameter does not really do anything. It doesn't convert one object in another, not does it give them types.
作为建议,在类型转换对服务的调用结果或从localStorage
,sessionStorage
等获取对象的结果时,切勿使用类.您应该改用没有方法的接口.
As an advice, you should never use classes when typecasting the result of calls to services or getting objects from localStorage
, sessionStorage
and such. You should use interfaces instead, without methods.
但是,如果您确实需要对象属于Foo
类并具有doSomething
方法,则可以实现所需的目标:
However, it is possible to achieve what you want, if you really need your objects to be of class Foo
and have the doSomething
method:
this.http.get<Foo[]>(...).do(items => items.forEach(item => Object.setPrototypeOf(item, Foo.prototype)));
这将为每个对象提供正确的原型.但是,这样做会降低性能,因为更改创建的对象的原型会干扰浏览器优化,因此请您自担风险.
This will give every object the correcto prototype. However, this has a performance penalty, as changing the prototype of created objects messes with browser optimization, so do it under your own risk.
另一种选择是为Foo
提供一个构造函数:
Another option would be to give Foo
a constructor:
class Foo {
constructor(item: Foo) {
Object.assign(this, item);
}
bar: string;
public doSomething() {}
}
现在:
this.http.get<Foo[]>(...).pipe(map(items => items.map(item => new Foo(item)))).subscribe(...);
这篇关于Angular HttpClient没有返回我期望的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!