【问题标题】:Angular HttpClient is not returning quite the objects I expectAngular HttpClient 没有返回我期望的对象
【发布时间】:2018-10-14 08:37:30
【问题描述】:

假设我有

class Foo {
    bar: string;

    public doSomething() {}

}

在我的服务中,我从服务器获取数组:

this.http.get<Foo[]>(...)

这行得通,我得到了所有的预期值。但是,当我获取我得到的一个对象并尝试对其调用 doSomething() 时,我收到一个错误消息,指出 foo(类型为 Foo)没有方法 doSomething()。

看起来,虽然 http.get 正确解析了 JSON 并分配了我的对象的所有属性,但它并没有为它们设置适当的原型而烦恼,所以基本上它们只是名义上的 Foos,它们缺少所有方法福。

这是正常的还是我做错了什么? 谢谢。

【问题讨论】:

标签: angular typescript


【解决方案1】:

有效。最后,您只是解析 JSON,解析 JSON 的结果只是普通的 JavaScript 对象,而不是自定义类。 this.http.get&lt;Foo[]&gt; 只是给编译器的一个提示,但泛型参数并没有真正做任何事情。它不会将一个对象转换为另一个对象,也不会给它们类型。

作为建议,在对服务调用的结果进行类型转换或从localStoragesessionStorage 等获取对象时,您不应该使用类。您应该改用接口,而不是方法。

但是,如果您确实需要您的对象属于 Foo 类并具有 doSomething 方法,则可以实现您想要的:

this.http.get<Foo[]>(...).do(items => items.forEach(item => Object.setPrototypeOf(item, Foo.prototype)));

这将为每个对象提供正确的原型。但是,这会降低性能,因为更改创建对象的原型会影响浏览器优化,因此需要您自担风险。

另一个选择是给Foo一个构造函数:

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(...);

【讨论】:

    【解决方案2】:

    你也可以像这样通过继承来做到这一点:

    this.http.get<Foo>(...)
        .pipe(Foo.serializeResponseMap());
    

    类定义:

    export class Foo extends SerializableMap {
        static instanceType = Foo;
    
        constructor() { super(); }
    
        bar: string;
    
        public doSomething() {}
    }
    
    
    class SerializableMap {
      static instanceType: any;
    
      static serializeResponseMap(): any {
        const createInstance = (r) => {
          return Object.assign(new this.instanceType(), r);
        };
    
        return map((respValue: any) => {
          if (Array.isArray(respValue)) {
            return respValue.map(r => createInstance(r));
          }
          return createInstance(respValue);
        });
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-05-30
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 2018-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多