json-mapper-class
v1.0.2
Published
Json Mapper To Class
Downloads
1
Readme
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
标准类 模版代码 的过程,本人开发第二个插件简化了过程,插件地址(请自信阅读文档):
下面是一个案例:
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 classoptions?
<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(映射成一个类实例) => deserializertoPlain/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: '[email protected]',
};
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: '[email protected]',
},
SerializeModel,
);
// 你将获得如下数据
{
e: '[email protected]',
}
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}',
};