将 JSON 转换为复杂类型
Casting JSON to complex types
我正在尝试将我的 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
中的所有属性复制到它。但是,当涉及到对象数组时,我开始面临问题。示例(使用简化的 class):
export class Person {
name:string;
age:number;
addresses:Address[] = [];
}
export class Address {
street:string;
city:string;
fullAddress() : string { return this.street + this.city; }
}
一旦我有了这种数组,item
中就没有任何初始对象了。这意味着没有 class 的初始构造函数导致简单的 Object
。 JavaScript 或 TypeScript 没有错误;然而,当我试图访问 class 的内部方法时(在我们的简化案例 fullAddress()
中,我将无法访问。
我需要它的原因是我在我的子 class 上重写了 toString()
方法,当您使用 [=22= 时,这对于 MatTableDataSource
是必需的] 方法(适用于字符串)。
有没有办法从 http.get()
中检索元素并将结果正确映射到类型化对象?
你太笼统了。您正在创建对象的对象,而不是具有子地址的 Product 的对象。
如果您想创建一个新产品,您将必须了解 api 的结果与您在 UI 中想要的数据之间的关系。
因为您使用的是 类 而不是接口,并且想要继承函数,所以将新地址获取到新对象的唯一方法是使用 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
。
我正在尝试将我的 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
中的所有属性复制到它。但是,当涉及到对象数组时,我开始面临问题。示例(使用简化的 class):
export class Person {
name:string;
age:number;
addresses:Address[] = [];
}
export class Address {
street:string;
city:string;
fullAddress() : string { return this.street + this.city; }
}
一旦我有了这种数组,item
中就没有任何初始对象了。这意味着没有 class 的初始构造函数导致简单的 Object
。 JavaScript 或 TypeScript 没有错误;然而,当我试图访问 class 的内部方法时(在我们的简化案例 fullAddress()
中,我将无法访问。
我需要它的原因是我在我的子 class 上重写了 toString()
方法,当您使用 [=22= 时,这对于 MatTableDataSource
是必需的] 方法(适用于字符串)。
有没有办法从 http.get()
中检索元素并将结果正确映射到类型化对象?
你太笼统了。您正在创建对象的对象,而不是具有子地址的 Product 的对象。
如果您想创建一个新产品,您将必须了解 api 的结果与您在 UI 中想要的数据之间的关系。
因为您使用的是 类 而不是接口,并且想要继承函数,所以将新地址获取到新对象的唯一方法是使用 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
。