如何使用TypeScipt解析复杂的json对象?
我有一个客户对象,他有一些发票。
这是我的模特:
export class Customer {
public id: string;
public name: string;
public invoices: CustomerInvoice[];
get invoicesCount(): number {
if (this.invoices== null) {
return 0;
}
return this.invoices.length;
}
constructor() {
}
}
export class CustomerInvoice {
public id: number;
constructor() {
}
}
在我的服务中,我有:
ngOnInit() {
if (this.id != null) {
this.dataService.getCustomer(this.id).subscribe(data => {
this.customer = data;
},
err => console.log(err));
}
}
客户数据很棒(我的客户ID,名称等都有一些值)但发票是空的。
json是正确的,data.Invoices.length返回一个数字。
答案 0 :(得分:8)
如何使用TypeScipt解析复杂的json对象?
假设您的意思是将JSON解析为实际的类实例而不是简单的Javascript对象,TypeScript不提供此功能现成的。
您可以创建一个接口声明,使用该接口声明可以执行type-assertion(而不是类型强制转换)来模仿类型安全性如果 JSON是可信的,但就是这样 - 我不知道将JSON序列化为用户定义类型的实际实例的原生工具。
interface ICustomerInvoice {
id: number;
}
interface ICustomer {
id: string;
name: string;
invoices: ICustomerInvoice[];
}
var customer: ICustomer = JSON.parse(json) as ICustomer;
然而,出于同样显而易见的原因,我开始将TypedJSON放在一起将此功能引入TypeScript。您可以使用JsonObject和JsonMember装饰器注释您的类和成员:
@JsonObject
export class CustomerInvoice {
@JsonMember
public id: number;
}
@JsonObject
export class Customer {
@JsonMember
public id: string;
@JsonMember
public name: string;
@JsonMember({ elementType: CustomerInvoice })
public invoices: CustomerInvoice[];
get invoicesCount(): number {
if (this.invoices== null) {
return 0;
}
return this.invoices.length;
}
}
要反序列化JSON字符串,您可以使用TypedJSON.parse而不是JSON.parse,getter也将按预期显示:
var customer = TypedJSON.parse(json, Customer);
typeof customer.invoicesCount; // "number"
推荐与ReflectDecorators一起使用(但不是必需的)。如果您选择跳过此建议,则还需要为成员指定“类型”设置,例如:
@JsonMember({ type: String })
public id: string;
答案 1 :(得分:0)
您可以使用rxjs的地图运算符手动映射您DataService
中的实体。
我还没有测试过代码,因此您可能需要使用rx(invoices.map(...))来映射发票以迭代集合,但原则仍然相同。
getCustomer(id: number): Observable<Customer> {
return this.http.get<Customer>(this.customerUrl).map(customer => {
let newCustomer = customer;
newCustomer.invoices = customer.invoices;
return newCustomer;
});
}