将JSON转换为复杂类型

时间:2019-01-08 15:36:55

标签: json angular typescript casting jsonserializer

我正在尝试将我的http.get响应投射到实际对象->在我的特殊情况下的复杂对象数组中。

在正常情况下,不需要任何特定的转换,可以执行以下操作(简化):

return this.httpClient.get(api, this._options_get)
  .pipe(
    map((response: any) => {
      return response.value as NewProduct[];
    })
  );

由于我需要将其实际转换为对象,因此我创建了一个静态方法来做到这一点:

static toProduct(otherProduct: any): NewProduct {
    let item = new NewProduct();

    Object.keys(otherProduct).forEach(prop => {
        if (typeof otherProduct[prop] === "object" && otherProduct[prop]) {
            if (!item.hasOwnProperty(prop))
                item[prop] = otherProduct[prop];
            Object.assign(item[prop], otherProduct[prop]);
        }
        else
            item[prop] = otherProduct[prop];
    })

    return item;
}

Object.assign下,我正在获取已存在的对象,该对象已在第一行下初始化,我只是将所有属性从otherProduct复制到它。但是,当涉及对象数组时,我开始面临问题。示例(具有简化的类):

export class Person {
    name:string;
    age:number;
    addresses:Address[] = [];
}
export class Address {
    street:string;
    city:string;
    fullAddress() : string { return this.street + this.city; }
}

一旦有了这种数组,item中就没有任何初始对象。这意味着没有类的初始构造函数产生简单的Object。对于JavaScript或TypeScript,这不是错误;但是,当我尝试访问类的内部方法时(在我们简化的情况下,fullAddress(),我将无法访问。

之所以需要这样做,是因为我在子类上覆盖了toString()方法,当您使用MatTableDataSource方法(该方法适用于字符串)时,这对于filter是必需的)。

有没有办法从http.get()检索元素并将结果正确映射到类型化的对象?

1 个答案:

答案 0 :(得分:0)

您太普通了。您正在创建对象的对象,而不是带有地址子代的Product对象。

如果要创建新产品,则必须了解api的结果与用户界面中所需数据之间的关系。

因为使用的是类而不是接口,并且要继承函数,所以将新地址放入新对象的唯一方法是使用new关键字。

您将不得不遍历。您不会为此找到捷径。您将需要遍历数据并对其进行转换。如果您的api为您提供了ApiPerson,则您需要执行以下操作:

const addresses = apiPerson.addresses.map((apiAddress) => {
    const address = new Address();
    // map properties of apiAddress to address...
    return address;
});

现在您有了addresses,可以将apiPerson映射到new Person()的属性,然后设置newPerson.addresses = address