【问题标题】:Parse array of JSON objects to array of TypeScript objects将 JSON 对象数组解析为 TypeScript 对象数组
【发布时间】:2020-05-02 02:29:17
【问题描述】:

我有一个返回这个 Json 的端点:

{
  "result": [
    {
      "id": 1,
      "name": "Kayak",
      "category": "Watersports",
      "description": "A boat for one person",
      "price": 27500,
      "currencyCode": "EUR"
    },
    {
      "id": 2,
      "name": "Lifejacket",
      "category": "Watersports",
      "description": "Protective and fashionable",
      "price": 48095,
      "currencyCode": "EUR"
    },
    {
      "id": 3,
      "name": "Soccer Ball",
      "category": "Soccer",
      "description": "FIFA-approved size and weight",
      "price": 1950,
      "currencyCode": "EUR"
    }
]
}

我在 Angular 中有一个名为 Product 的类:

import { Money, Currencies } from 'ts-money';

export class Product {
private money: Money;
public Amount = this.money.amount;

public constructor(
    public Id: number,
    public Name: string,
    public Category: string,
    public Price: number,
    public Description: string,
    public CurrencyCode: string) {
        this.money = new Money(Price, CurrencyCode);
    }

public GetPrice(): Money {
    return this.money;
}
}

我在 Angular 中编写了这段代码:

export class ProductComponent implements OnInit {

  constructor(private datasource: ProductDataSource) {
  }

  private products: Product[];

  ngOnInit(): void {
    this.datasource.GetProducts()
    .subscribe((data) => {
        this.products = data;
    });
  }
 }
}

此代码成功返回与Product 具有相同属性的 JSON 对象数组。现在,当我订阅这个 observable 时:

this.datasource.GetProducts()
.subscribe((data) => {
    // this.products is a class property of type Product[]
    this.products = data; // How do I make this work?
});

我不知道如何从 JSON 对象转换到 Angular 类。我的 HTML 页面无法将 this.products 识别为 Product 对象的数组。我该怎么办?

【问题讨论】:

  • 如何在您的组件中声明/初始化this.products 以及您如何在模板中使用它?你能把这个添加到你的问题中吗?

标签: angular


【解决方案1】:

我认为这是因为您在产品类中的映射以及您的类的类型,请尝试将类 Product 更改为接口 Product

喜欢这个

    export interface Product{

    public id: number;
    public name: string;
    public category: string;
    public price: number;
    public description: string;
    public currencyCode: string; 

 }

你可以去Angular : Class and Interface看看类和接口的区别

编辑:(正如您在我的代码中看到的,我还更改了变量名以匹配您的 JSON 响应)

【讨论】:

    【解决方案2】:

    使用变量创建产品接口并使用该接口创建数组

        export interface Product{
          public Id: number,
          public Name: string,
          public Category: string,
          public Price: number,
          public Description: string,
          public CurrencyCode: string
        }
    
         products:Product[];
    

    【讨论】:

    • @Random 它取决于你的项目是如何设置的,从 JSON 中你可以看到它是 camelCase 而不是 PascalCase
    • 我说的是接口名称,而不是属性。实际上,属性名称取决于服务器响应的内容,但应该是 camelCase(在问题中,属性是 PascalCase,这很奇怪)
    【解决方案3】:

    Product 属性名称和 json 属性名称不匹配。 你可以这样做:

    this.datasource.GetProducts()
      .subscribe((data) => {
        // this.products is a class property of type Product[]
        this.products = (data || []).map(item => new Product(item.id, item.name, item.category, item.price, item.description, item.currencyCode))
      });
    

    【讨论】:

    • 更容易将产品从类更改为接口,并在接口内进行正确的 JSON 映射,这种映射不会增加复杂性
    • 完全同意,但映射仍然是一种选择
    • 您也可以使用new Product(item) 并在构造函数中移动复杂性...
    • 我没有说这不是一个选择,我认为有更好的方法可以这样做:)
    • @Random,如果 Product 和 json 中的属性名称不匹配(正如我们在一个问题中所遇到的。产品属性名称大写) - 这将不起作用。
    【解决方案4】:

    将类改成接口,也改大小写。

    export interface Product{
    
    public id: number;
    public name: string;
    public category: string;
    public price: number;
    public description: string;
    public currencyCode: string; }
    

    【讨论】:

    • "just",还要把"class"改成"interface"...^^
    【解决方案5】:

    另一种方法是使 JSON 数据与您的 Product 类兼容。您可以使用 ma​​p rxjs 运算符将您的 JSON 数据转换为 Product。修改获取产品代码,像这样

        const source$ = of(result).pipe(pluck('result'),map(item=> item.map(x=>{
          let product = new Product(x.id,x.name, x.category, x.price, x.description, x.currencyCode);
          return product;
        })));

    这是一个StackBlitz 链接。

    【讨论】:

    • rxjs 是一个很好的方法,但是将它与 of 一起使用很奇怪。你可以在datasource.GetProducts() 方法中做同样的事情(问题中没有详细说明),直接在http调用上
    • 是的。实际上,我只是将其作为示例编写,只是为了在我的 stackblitz 代码中重现该场景。
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-13
    相关资源
    最近更新 更多