鸿蒙Next开发json转模型方案 class-transformer

引入必备的三方框架

  "dependencies": {
    "reflect-metadata": "^0.1.13",
    "class-transformer": "^0.5.1"
  },
import 'reflect-metadata'
import { Expose, Type, plainToInstance } from 'class-transformer'
import { ObservedArray } from 'commlib'

@Observed
export class HFHotStockModel {
  @Expose({ name: 'code' })
  stockCode: string = ''
  @Expose({ name: 'name' })
  stockName: string = ''
  @Expose({ name: 'tag' })
  tagName?: string = ''
  lastPrice: string = ''
  priceRange: string = ''
  @Expose({ name: 'hot' })
  hotValue: number|null = null
  stockType: number = 0
  isSelected: boolean = true

}
@Observed
export class HFHotStockSectionModel {
  title: string|null = null
  @Type(() => HFHotStockModel)
  stocks: ObservedArray<HFHotStockModel> = []

}
@Observed
export class HFHotStockTabDataModel {
  @Expose({ name: 'from' })
  sourceID: string =''
  @Expose({ name: 'name' })
  sourceName: string =''
  @Type(() => HFHotStockSectionModel)
  content: HFHotStockSectionModel[] =[]

  public static plainToModel(obj: Object): HFHotStockTabDataModel {
    return plainToInstance(HFHotStockTabDataModel, obj)
  }
}

@Observed
export class HFHotFundModel {
  @Expose({ name: 'fundCode' })
  fundCode: string = ''
  @Expose({ name: 'fundName' })
  fundName: string = ''
  riskLevel: string = ''
  fundType: string = ''
  @Expose({ name: 'tip' })
  upDownPercentMark: string = ''
  upDownPercent: string|null|undefined
  isSelected: boolean = true
}

@Observed
export class HFHotFundSectionDataModel {
  markName?: string
  groupName?: string
  @Type(() => HFHotFundModel)
  funds: HFHotFundModel[] = []

  public static plainToModel(obj: Object): HFHotFundSectionDataModel {
    return plainToInstance(HFHotFundSectionDataModel, obj)
  }
}

定义的Interface

export interface HFHotStockEntityI {
  name: string
  code: string
  tag: string
  upDownValue: string
  upDownPercent: string
  hot: string
}
export interface HFHotStockSectionEntityI {
  title: string
  stocks: HFHotStockEntityI[]
}
export interface HFHotStockDataModelI {
  from: string
  name: string
  content: HFHotStockSectionEntityI[]
}

export interface HFHotResponseDataModelI {
  data: HFHotStockDataModelI[]
}

export interface HFHotFundEntityI {
  fundName: string
  fundCode: string
  riskLevel: string
  fundType: string
  tip: string
  upDownPercent: string
}
export interface HFHotFundGroupModelI {
  markName: string
  groupName: string
  funds: HFHotFundEntityI[]
}

使用的地方,业务代码

  public async pullHFHotStockDataNet(): Promise<HFHotStockTabDataModel[]> {
    try {
      const data = await this.hotStockNet.getHotStocks()
      const groupModelList = data.map((item: HFHotStockDataModelI, index: number) => {
        const group: HFHotStockTabDataModel = HFHotStockTabDataModel.plainToModel(item)
        return group
      })
      return groupModelList
    } catch (error) {
      return Promise.reject(error)
    }
  }

  public async pullHFHotFundDataNet(): Promise<HFHotFundSectionDataModel[]> {
    try {
      const data = await this.hotStockNet.getHotFunds()
      const groupModelList = data.map((item: HFHotFundGroupModelI, index: number) => {
        const group: HFHotFundSectionDataModel = HFHotFundSectionDataModel.plainToModel(item)
        return group
      })
      return groupModelList
    } catch (error) {
      return Promise.reject(error)
    }
  }

类模型就自动生成好了,免去手动赋值。类似于iOS的 YYModel、MJExtension框架。

下面详细介绍

class-transformer 是一个流行的 TypeScript 库,用于在对象之间进行转换。它可以帮助你在 JavaScript 对象和类实例之间进行序列化和反序列化操作。这对于处理 API 响应、验证数据以及将数据映射到特定的类结构非常有用。

下面是一个详细的示例,展示如何使用 class-transformer 进行对象转换。

安装依赖

首先,你需要安装 class-transformerreflect-metadatareflect-metadata 是一个运行时反射库,class-transformer 依赖于它来获取类型信息。

npm install class-transformer reflect-metadata

示例代码

假设我们有一个简单的用户类,并且我们需要从 JSON 数据中创建这个类的实例。

1. 定义类

首先,定义一个简单的用户类,并使用 @Expose@Transform 装饰器来控制属性的暴露和转换行为。

2. 使用 plainToClass 进行转换

接下来,使用 plainToClass 函数将普通的 JavaScript 对象转换为 User 类的实例。

3. 使用 classToPlain 进行转换

同样地,可以使用 classToPlain 函数将 User 类的实例转换回普通的 JavaScript 对象。

完整示例

以下是完整的示例代码,展示了如何定义类并进行双向转换。

解释

  1. 导入必要的模块

    • reflect-metadata:提供运行时反射能力。
    • class-transformer:提供 plainToClassclassToPlain 等函数。
  2. 定义类

    • 使用 @Expose 装饰器来指定哪些属性应该被包含在转换过程中,并可以重命名属性名称。
    • 使用 @Transform 装饰器来对属性进行自定义转换,例如将字符串日期转换为 Date 对象。
  3. 转换过程

    • 使用 plainToClass 将普通对象转换为类实例。
    • 使用 classToPlain 将类实例转换回普通对象。
import "reflect-metadata";
import { Expose, Transform, plainToClass, classToPlain } from "class-transformer";

class User {
    @Expose()
    id: number;

    @Expose({ name: 'first_name' })
    firstName: string;

    @Expose({ name: 'last_name' })
    lastName: string;

    @Expose()
    email: string;

    @Expose()
    age: number;

    @Expose({ name: 'created_at' })
    @Transform(({ value }) => new Date(value))
    createdAt: Date;
}

const userData = {
    id: 1,
    first_name: "John",
    last_name: "Doe",
    email: "john.doe@example.com",
    age: 30,
    created_at: "2023-01-01T00:00:00Z"
};
const userInstance = plainToClass(User, userData);
console.log("Converted to Class Instance:", userInstance);

const plainObject = classToPlain(userInstance);
console.log("Converted back to Plain Object:", plainObject);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容