使用 TypeScript 解析复杂的 json 对象



如何使用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 是正确的,数据。发票长度返回一个数字。

如何使用TypeScipt解析复杂的json对象?

假设你的意思是将JSON解析到实际的类实例而不是简单的Javascript对象中,TypeScript不会提供现的这个功能。

如果 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"    

建议与反射装饰器一起使用(但不是必需的)。如果您选择跳过此建议,则还需要为成员指定"类型"设置,例如:

@JsonMember({ type: String })
public id: string;
您可以使用

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;
    });
}

最新更新