如何确保我的json结构映射到我的界面?

时间:2018-03-23 16:08:49

标签: angular typescript

所以,我对产品信息api的预期json响应如下:

{
    _productDepartment : null,
    _productClass : null,
    _productMaterial : null,
    _productStyle : null,
    _productDetails :
    {
        _productSkuKey : 800,
        _description : "Product Description",
        _collection : "Collection1",
        _department : 200,
        _productSize : "Size1",
        _productClass : 45,
        _productStyle : 1234,
        _material : "Product Material",
        _price : 100.00,
        _mediaFileName : "XYZ"
    },
    _products : null,
    _errorDetails :
    {
        _message : "success",
        _status : 200
    }
}

对于这个特定的api调用,我最感兴趣的是productDetails信息和errorStatus。我想基于上面的json响应创建一个productDetails对象,所以我创建了两个接口,一个用于产品,一个用于productdetails。

以下是我的界面:

//product.ts
import { IProductDetails } from './productDetails';

export interface IProduct {

    productDepartment: string;
    productClass: string;
    productMaterial: string;
    productStyle: string;
    productDetails: IProductDetails;
    products: null;
    errorDetails: string;

}

//productDetails.ts
export interface IProductDetails {
    productSkuKey: number;
    description: string;
    collection: string;
    department: number;
    productSize: string;
    productClass: string;
    productStyle: number;
    material: string;
    price: string;
    mediaFileName: string;
}

在我的一项服务中,我接到了这个电话:

getProducts(storeId: string, productSKU: string) {
    this.products = this.baseUrl + '/products/' + storeId + '/' + productSKU;
    return this.http.get<IProduct[]>(this.products).catch(this.errorHandler);
  }

在我的一个组件中,我称之为服务:

this._transactionService.getProduct('98', '343').subscribe(data => this.products = data._productDetails);

我的问题是,这是确保我在代码中使用的对象与json响应数据匹配的正确方法吗?如何在我的界面中将_productSkuKey与productSkuKey映射?

2 个答案:

答案 0 :(得分:2)

接口的结构和JSON的结构必须是等效的,这意味着属性应具有相同的名称。

因此,您必须将下划线添加到接口,或从服务中删除它们。

但是,确保无法使您的界面与服务中的JSON匹配。通过定义界面,您可以告诉TypeScript您期望的内容。它不会阻止您接收不同的内容,因为类型信息在编译后消失

答案 1 :(得分:1)

如果您因某些原因不想使用下划线更改界面道具,而不是Interface您可以Class这样的内容:

export class SomeClass {
  productDepartment = 0;
  productClass = 0;

  constructor(data: any) {
    for (let prop of Object.keys(data)) {

      if (this.hasOwnProperty(prop)) {
        this[prop] = data[prop];
      } else {
        let gProp = prop.substring(1);
        if (this.hasOwnProperty(gProp)) {
          this[gProp] = data[prop];
        }
      }
    }
  }
}
...
 this.data = new SomeClass({
  _productDepartment: 12,
  _productClass: 34
});

将返回:

SomeClass {productDepartment: 12, productClass: 34}

CODE EXAMPLE

在您的服务中:

getProducts(storeId: string, productSKU: string) {
    this.products = this.baseUrl + '/products/' + storeId + '/' + productSKU;
    return this.http.get<Product[]>(this.products)
     .map(prodRes => prodRes.map(prod => new Product(prod)))
     .catch(this.errorHandler);
  }