数据引用
基本概念
在前面模板语法中我们已经学习到了如何在模板中使用引用数据
ts
{
字段: {
refModel: '模型名称' | '模型对象';
// 生成数量
count?: number;
// 递归深度
deep?: number;
},
// 或者,此时count和deep属性默认为1
字段:'模型名称' | '模型对象'
}本节将继续介绍引用数据的高级用法
默认配置
在模板中引用数据时,我们可以指定引用数据生成的数量和递归深度,这样在数据生产时就会按照相应的数量和深度来生成数据。
生成数量
ts
const addressModel = defineModel('address', {
country: 'location.country',
city: 'location.city',
});
// 用户模型
const userModel = defineModel('user', {
firstName: 'person.firstName',
secondName: 'person.lastName',
age: ['number.int', { min: 18, max: 65 }],
address: { refModel: 'address', count: 2 },
});
const userDatas = fakeData(userModel);
console.dir(userDatas, { depth: Infinity });上面的案例中我们指定了address字段的count属性为2,因此在生成userDatas时,address字段会生成两个数据。生成的数据如下:
ts
{
firstName: 'Anibal',
secondName: 'Douglas-Crooks',
age: 62,
address: [
{ country: 'Hungary', city: 'Emoryton' },
{ country: 'Venezuela', city: 'New Marcelfurt' }
]
}递归深度
如果存在自引用,比如生成树状数据,我们就需要指定递归深度了,因为如果不限制递归深度会导致栈溢出
ts
const addressModel = defineModel('address', {
country: 'location.country',
city: 'location.city',
children: {
refModel: 'address',
count: 2,
deep: 1,
},
});
// 用户模型
const userModel = defineModel('user', {
firstName: 'person.firstName',
secondName: 'person.lastName',
age: ['number.int', { min: 18, max: 65 }],
address: { refModel: 'address', count: 2 },
children: {
refModel: 'user',
deep: 2,
},
});
const userDatas = fakeData(userModel);
console.dir(userDatas, { depth: Infinity });上面的案例中address和user都存在自引用,我们指定了address的deep属性为1,user的deep属性为2,因此在生成userDatas时,address和user字段会生成相应的深度。并且,我们可以同时指定生成的数量,所以生成的数据如下:
json
{
"firstName": "Lydia",
"secondName": "Adams",
"age": 41,
"address": [
// 第一个address数据
{
"country": "Democratic Republic of the Congo",
"city": "Elisefurt",
// 递归1层
"children": [
{
"country": "Nauru",
"city": "Randalltown"
},
{
"country": "Afghanistan",
"city": "Commerce City"
}
]
},
// 第二个address数据
{
"country": "Ecuador",
"city": "Hamillworth",
"children": [
{
"country": "Reunion",
"city": "West Greysonland"
},
{
"country": "Italy",
"city": "Hempstead"
}
]
}
],
// 第一层children
"children": {
"firstName": "Lisette",
"secondName": "Gutmann",
"age": 29,
"address": [
{
"country": "Syrian Arab Republic",
"city": "Leuschkefield",
"children": [
{
"country": "Austria",
"city": "Hammesstad"
},
{
"country": "Barbados",
"city": "West Elodyfort"
}
]
},
{
"country": "Colombia",
"city": "Fort Anastasia",
"children": [
{
"country": "Czechia",
"city": "Hyattfort"
},
{
"country": "Zambia",
"city": "West Stefanieborough"
}
]
}
],
// 第二层children
"children": {
"firstName": "Rex",
"secondName": "Farrell",
"age": 22,
"address": [
{
"country": "El Salvador",
"city": "Montyshire",
"children": [
{
"country": "Bangladesh",
"city": "Port Prince"
},
{
"country": "Svalbard & Jan Mayen Islands",
"city": "South Siennacester"
}
]
},
{
"country": "Panama",
"city": "Monterey Park",
"children": [
{
"country": "Vietnam",
"city": "South Scotworth"
},
{
"country": "Mozambique",
"city": "Matildeside"
}
]
}
]
}
}
}运行时配置
但是有些时候我们并不想使用模板中定义的默认配置,我们可以在fakeData的第二个参数中直接配置引用数据的生成规则,这个配置的优先级大于默认的模板配置,其配置方式如下:
ts
type RefModelRule = {
/**
* 生成数量
*/
[COUNT]?: number;
/**
* 引用自身时的递归深度
*/
[DEEP]?: number;
/**
* 结构递归
*/
[key: string | symbol]: number | RefModelRule | [number, number];
};[COUNT]和[DEEP]
为了避免属性冲突我们需要使用DataFaker提供的两个symbol属性,COUNT和DEEP,他们分别代表生成数量和递归深度的配置,其他的属性则代表结构递归的配置。
ts
const addressModel = defineModel('address', {
country: 'location.country',
city: 'location.city',
children: {
refModel: 'address',
count: 2,
deep: 1,
},
});
// 用户模型
const userModel = defineModel('user', {
firstName: 'person.firstName',
secondName: 'person.lastName',
age: ['number.int', { min: 18, max: 65 }],
address: { refModel: 'address', count: 2 },
children: {
refModel: 'user',
deep: 2,
count: 2,
},
});
const userDatas = fakeData(userModel, {
refRules: {
// address引用数据生成一个,然后其address.childern自引用数据生成一个
address: {
[COUNT]: 1,
children: {
[COUNT]: 1,
},
},
// 自引用递归深度为1,且只生成一个,address引用属性同上
children: {
[DEEP]: 1,
[COUNT]: 1,
},
},
});
console.dir(userDatas, { depth: Infinity });上面的案例中
- address 引用数据生成一个,然后其 address.childern 自引用数据生成一个
- 自引用递归深度为 1,且只生成一个,address 引用属性同上
所以生成的数据如下:
json
{
"firstName": "Jeremy",
"secondName": "Hettinger",
"age": 50,
// 生成一个
"address": {
"country": "Cayman Islands",
"city": "Orlandoview",
// 递归深度1
"children": { "country": "Dominica", "city": "Boynton Beach" }
},
// 递归深度为1,且生成一个
"children": {
"firstName": "Sigrid",
"secondName": "Kassulke",
"age": 62,
"address": {
"country": "Turkmenistan",
"city": "Anthonyborough",
"children": { "country": "French Guiana", "city": "Schaumburg" }
}
}
}配置优先级
从上面的案例就可以看出,配置的优先级是:运行时配置 > 模板