json-mapper-class
TypeScript icon, indicating that this package has built-in type declarations

1.0.2 • Public • Published

json-mapper-class

json-mapper-class 是类似flutter Json序列化的 web前端 优雅 解决方案,用来将接口 json 数据映射到 class 的工具,之后在我们的TypeScript项目中,可以通过 类来为接口返回数据标注类型,通过修改类属性达到不需要后端修改接口数据字段的情况下,前端来任意定义接口返回字段的效果,解决了实际项目中接口数据与页面深度耦合的过程,并提供其逆过程。

json-mapper-class 是一个独立的插件,可以与任何的 TypeScript 项目进行深度的集成(最好是class语法),同时提供了众多的装饰器,让你更加优雅的去编写 TypeScript,请仔细阅读文档。

同时为了方便 json-mapper-class 的方法 toClass 第二个参数的生成,也是为了避免手动编写json-mapper-class 标准类 模版代码 的过程,本人开发第二个插件简化了过程,插件地址(请自信阅读文档):

json-class-interface

下面是一个案例:

import { property, toClass } from 'json-mapper-class';

class UserModel {
  @property('i')
  id: number;

  @property()
  name: string;
}

const userRaw = {
  i: 1234,
  name: 'name',
};

// 使用 toClass 将 json 转换成 class
const userModel = toClass(userRaw, UserModel);
// 你将获得如下数据
{
  id: 1234,
  name: 'name',
}

如何安装

npm i json-mapper-class --save

使用例子

聚合对象或数组

如果你想转换一个聚合对象,需要提供目标类。如果该对象的某个属性值是数组,则会递归该数组的所有元素(不管层级有多深),自动转换为目标类的实例。

列子:

class NestedModel {
  @property('e', UserModel)
  employees: UserModel[];

  @typed(UserModel)
  @property('u')
  user: UserModel;
}

const model = toClass(
  {
    e: [
      { i: 1, n: 'n1' },
      { i: 2, n: 'n2' },
    ],
    u: {
      i: 1,
      n: 'name',
    }
  },
  NestedModel,
);
// you will get like this
{
  employees: [
    { id: 1, name: 'n1' },
    { id: 2, name: 'n2' },
  ],
  user: {
    id: 1,
    name: 'name'
  }
}

const model = toPlain(
  {
    employees: [
      { id: 1, name: 'n1' },
      { id: 2, name: 'n2' },
    ],
    user: {
      id: 1,
      name: 'name'
    }
  },
  NestedModel,
);
// you will get like this
{
  e: [
    { i: 1, n: 'n1' },
    { i: 2, n: 'n2' },
  ],
  u: {
    i: 1,
    n: 'name'
  }
}

其他数据类型转换

import * as moment from 'moment';

export class EduModel {
  @property('i')
  id: number;

  @property('crt')
  @deserialize(value => moment(value).format('YYYY-MM-DD HH:mm:ss'))
  createTime: string;
}

依赖于其他属性值

class EmailModel {
  @property('s')
  site: string;

  @property('e')
  @deserialize((value, _instance, origin) => `${value}@${origin.s}`)
  email: string;
}

方法

toClass(raw, clazzType, options?) / toClasses(raws, clazzType, options?)

将一个 json 对象映射成一个类实例

  • raw / raws <Object|Array<Object>> 一个 josn 对象或者 json 对象数据
  • clazzType <Class> 类的构造函数
  • options? <Object> 配置
    • ignoreDeserializer <Boolean> 当设置为 true 时,不会调用使用 @deserialize 装饰器配置的方法
    • ignoreBeforeDeserializer <Boolean> 当设置为 true 时,不会调用使用 @beforeDeserialize 装饰器配置的方法
    • distinguishNullAndUndefined <Boolean> 当设置为 true 时,区分 null 和 undefined

示例:

const userRaw = {
  i: 1234,
  name: 'name',
};
const userRaws = [
  {
    i: 1000,
    name: 'name1',
  },
  {
    i: 2000,
    name: 'name2',
  },
];
const userModel = toClass(userRaw, UserModel);
const userModels = toClasses(userRaws, UserModel);

toPlain(instance, clazzType, options?) / toPlains(instances, clazzType, options?)

将一个类实例或者 json 对象映射成另外一个 json 对象

  • instance / instances <Object|Array<Object>> 一个 json 或类实例,或者一个json或类实例组成的数组
  • clazzType <Class> Constructor of the target class
  • options? <Object> 类的构造函数
    • ignoreSerializer <Boolean> 当设置为 true 时,不会调用使用 @serialize 装饰器配置的方法
    • ignoreAfterSerializer <Boolean> 当设置为 true 时,不会调用使用 @afterSerialize 装饰器配置的方法
    • distinguishNullAndUndefined <Boolean> 当设置为 true 时,区分 null 和 undefined

示例:

const userModel = {
  id: 1234,
  name: 'name',
};
const userModels = [
  {
    id: 1000,
    name: 'name1',
  },
  {
    id: 2000,
    name: 'name2',
  },
];
const userRaw = toPlain(userModel, UserModel);
const userRaws = toPlains(userModels, UserModel);

属性装饰器

调用不同的方法时,这些装饰器的执行顺序:

  • toClass/toClasses: beforeDeserializer => typed(映射成一个类实例) => deserializer
  • toPlain/toPlains: serializer => typed(映射成一个对象) => afterSerializer

property(originalKey?, clazzType?, optional = false)

将一个 key 映射到另外一个 key,如 n => name

  • originalKey <string> 被映射的数据 key, 如果不传则默认同名
  • clazzType <Class> 自动将该属性的值映射到一个类实例,相当于调用了 toClass 方法
  • optional <Boolean> 是否可选

示例:

class PropertyModel {
  @property('i')
  id: number;

  @property()
  name: string;

  @property('u', UserModel)
  user: UserModel;

  @property('t', null, true)
  timeStamp: number;
}

const model = toClass({ i: 234, name: 'property', u: { i: 123, n: 'name' } }, PropertyModel);
// 你将获得如下数据
{
  id: 234,
  name: 'property',
  user: {
    id: 123,
    name: 'name'
  }
}

typed(clazzType)

设置一个目标类的构造器,相当于 property 装饰器的第二个参数

  • clazzType <Class> 自动将该属性的值映射到一个类实例,相当于调用了 toClass 方法

示例:

// 与此设置一致 @property('n', UserModel)
class TypedModel {
  @typed(UserModel)
  @property('u')
  user: UserModel;
}

const model = toClass({ u: { i: 123, n: 'name' } }, TypedModel);
// 你将获得如下数据
{
  user: {
    id: 123,
    name: 'name'
  }
}

optional()

设置一个属性为可选,相当于 property 装饰器的第三个参数

示例:

// 与此设置一致 @property('n', null, true)
class OptionalModel {
  @optional()
  @property('n')
  name: string;
}

const model = toClass({}, OptionalModel);
// 你将获得如下数据
{
}

const model = toClass({ n: 'name' }, OptionalModel);
// 你将获得如下数据
{
  name: 'name';
}

defaultVal(val)

给当前属性设置默认值

  • val <Any> 要设置的默认值

示例:

class DefaultValModel {
  @defaultVal(0)
  @property('i')
  id: number;
}

const model = toClass({}, DefaultValModel);
// 你将获得如下数据
{
  id: 0;
}

const raw = toPLain({}, DefaultValModel);
// 你将获得如下数据
{
  i: 0;
}

serializeTarget()

当调 toPlain 进行序列化时,用使用当前数据作为基准

示例:

class SerializeTargetModel {
  @serializeTarget()
  @property('n')
  name: string;

  @property('n')
  nick: string;
}

const raw = toPlain(
  {
    name: 'name',
    nick: 'nick',
  },
  SerializeTargetModel,
);

// 你将获得如下数据
{
  n: 'name';
}

beforeDeserialize(beforeDeserializer, disallowIgnoreBeforeDeserializer = false)

@typed 调用之前调用

  • beforeDeserializer <(value: any, instance: any, origin: any) => any>
    • value <Any> 该属性在原始对象中的值
    • instance <Instance> 类实例(未完成解析)
    • origin <Object> 原始对象
  • disallowIgnoreBeforeDeserializer <Boolean> 默认为 false,如果设置为 true,则当调用 toClass 时,将强制调用 @beforeDeserialize 配置的方法

示例:

class BeforeDeserializeModel {
  @beforeDeserialize((value: any) => JSON.parse(value))
  @property('m')
  mail: object;
}

toClass(
  {
    m: '{"id":123}',
  },
  BeforeDeserializeModel,
);

// 你将获得如下数据
{
  mail: { id: 123 },
};

deserialize(deserializer, disallowIgnoreDeserializer =false)

将原始对象序列化成自定义的数组格式,仅在调用 toClass/toClasses 时可用

  • deserializer (value: any, instance: any, origin: any) => any
    • value <Any> 该属性的值经过 @beforeDeserialize@typed 调用后的结果
    • instance <Instance> 类实例(未完成解析)
    • origin <Object> A raw object
  • disallowIgnoreDeserializer <Boolean> 默认为 false,如果设置为 true,则当调用 toClass 时,将强制调用 @deserialize 配置的方法

示例:

class DeserializeModel {
  @deserialize((value: string) => `${value}@xxx.com`)
  @property('m')
  mail: string;
}

toClass(
  {
    m: 'mail',
  },
  DeserializeModel,
);

// 你将获得如下数据
{
  mail: 'mail@xxx.com',
};

serialize(serializer, disallowIgnoreSerializer = false)

自定义属性值的序列化方式,仅当调用 toPlain/toPlains 时可用

  • serializer (value: any, instance: any, origin: any) => any
    • value <Any> 该属性在类实例中的值
    • instance <Instance> 当前类实例
    • origin <Object> 一个json对象(未完成序列化)
  • disallowIgnoreSerializer <Boolean> 默认为 false,如果设置为 true,则当调用 toClass 时,将强制调用 @serialize 配置的方法

Example:

class SerializeModel {
  @serialize((mail: string) => mail.replace('@xxx.com', ''))
  @property('e')
  mail: string;
}

toPlain(
  {
    mail: 'mail@xxx.com',
  },
  SerializeModel,
);

// 你将获得如下数据
{
  e: 'mail@xxx.com',
}

afterSerialize(afterSerializer, disallowIgnoreAfterSerializer = false)

Convert a key/value in instance to a target form data, it happened after serializer only

  • afterSerializer (value: any, instance: any, origin: any) => any
    • value <Any> 该属性的值经过 @serializer@typed 调用后的结果
    • instance <Instance> 当前类实例
    • origin <Object> 一个json对象(未完成序列化)
  • disallowIgnoreAfterSerializer <Boolean> 默认为 false,如果设置为 true,则当调用 toClass 时,将强制调用 @afterSerialize 配置的方法

示例:

class AfterSerializeModel {
  @afterSerialize((mail: string) => JSON.stringify(mail))
  @property('e')
  mail: string;
}

toPlain(
  {
    mail: { id: 1000 },
  },
  SerializeModel,
);

// 你将获得如下数据
{
  e: '{"id":1000}',
};

Package Sidebar

Install

npm i json-mapper-class

Weekly Downloads

0

Version

1.0.2

License

none

Unpacked Size

40 kB

Total Files

24

Last publish

Collaborators

  • bmy