【问题标题】:How to map JSON to TypeScript objects with calculated properties如何将 JSON 映射到具有计算属性的 TypeScript 对象
【发布时间】:2018-03-27 10:05:19
【问题描述】:

我有一个相当标准的服务返回一些 JSON。

一个示例返回正文可能是:

[{ a: 1, b: 2 }]

我想将此映射到以下 Typescript 类的实例:

export class MyClass {
  a: number;
  b: number;

  get c() : number {
      return this.a + this.b;
  }
}

我错误地认为HttpClient.get 会这样做,但是虽然它确实将其映射到兼容对象,但它们缺少该属性。

this.http.get<MyClass[]>('http://www.example.com/endpoint');

有没有办法让 Angular 自动执行此操作,或者我需要像这样手动映射:

.map(data => {
    const results : MyClass[];
    for(const d of data) {
        const mc = new MyClass();
        mc.a = d.a;
        mc.b = d.b;
        results.push(mc);
    }
    return results;
});

它可以工作,但编写代码很繁琐,并且可以轻松地在我的代码中创建我不想要的依赖项。

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    1) 你可以创建一些解析函数,比如

    const mapJsonToObject = Type => obj => Object.assign( new Type(), obj );
    

    并像使用它

    ...
    .map( data => mapJsonToObject(MyClass) )
    ...
    

    2) 另外,你可以在类构造函数中分配所有属性

    export class MyClass {
      a: number;
      b: number;
    
      constructor(obj: MyClass) {
        Object.assign( this, obj );
      }
    
      get c() : number {
          return this.a + this.b;
      }
    }
    

    map 中只需创建MyClass 的新实体

    ...
    .map( data => new MyClass( data as MyClass ) )
    ...
    

    【讨论】:

    • @H.B.击败你,但对于简单的情况,这是一个更好的解决方案,谢谢。
    【解决方案2】:

    Angular 无法访问这样的泛型类型参数。它只是一个编译器注释。在 JSON 映射的情况下,我倾向于在目标类中编写一个静态解析函数,然后只在其上编写 map 普通对象。

    如果您不修改类名和属性,则可以使用键迭代在一定程度上自动映射属性(仅适用于没有太多额外代码的简单类型)。

    【讨论】:

    • 啊..不是我希望的答案,但仍然是一个答案,谢谢:)(稍后我会接受)
    • 在这种简单的情况下,Object.assign 实际上已经让你到达那里:Object.assign(new MyClass(), d)
    猜你喜欢
    • 2019-04-08
    • 2021-07-14
    • 2023-03-29
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多