本文介绍对象组(v.object() / v.looseObject() / v.strictObject())在聚合值时的行为:模型里多出来的键怎么处理、键怎么动态新增、聚合不出值时输出什么。
模型里存在、schema 里没有的键,由 groupMode 决定怎么处理。groupMode 在解析 schema 时自动推导:
| schema |
自动推导 |
多余键的处理 |
v.object() |
default |
输出时丢弃,只留 schema 定义的键 |
v.looseObject() |
loose |
保留并输出 |
v.strictObject() |
strict |
验证失败 |
v.record() / v.objectWithRest() 的 rest 部分 |
reset |
不做固定键约束,键可动态新增 |
下面三个示例的初始模型都带一个 schema 里没有的 extraKey,对比 __helper 里输出的值:
object-group-default.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
k1: v.string(),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
export const model = { k1: 'v1', extraKey: 'schema 未定义的键' };
object-group-loose.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.looseObject({
k1: v.string(),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
export const model = { k1: 'v1', extraKey: 'schema 未定义的键' };
object-group-strict.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.strictObject({
k1: v.string(),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
export const model = { k1: 'v1', extraKey: 'schema 未定义的键' };
v.intersect() 解析出的是逻辑组,用 asVirtualGroup() 转成普通表单组之后,可以手动指定 groupMode:
object-group-virtual-mode.definition.ts
import * as v from 'valibot';
import {
asVirtualGroup,
formConfig,
NFCSchema,
setComponent,
} from '@piying/view-angular-core';
export const schema = v.pipe(
v.intersect([
v.object({
a: v.string(),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
}),
]),
asVirtualGroup(),
formConfig({ groupMode: 'loose' }),
);
export const model = { a: '11' };
v.objectWithRest() 固定一部分键,其余键值按 rest 的类型动态添加;v.record() 的键值全部可动态添加。两者都推导为 reset:
object-with-rest.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.intersect([
v.objectWithRest(
{
k1: v.string(),
k2: v.number(),
},
v.string(),
),
v.optional(
v.object({
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
}),
),
]);
export const model = { k1: 'v1', k2: 2 };
新增键时,键名要先过一次 groupKeySchema,不通过的键不会被创建:
record-group-key-value.definition.ts
import * as v from 'valibot';
import { formConfig } from '@piying/view-angular-core';
export const schema = v.pipe(
v.record(v.string(), v.string()),
formConfig({
groupKeySchema: v.picklist(['name', 'email', 'phone']),
groupValueSchema: v.pipe(v.string(), v.minLength(1)),
}),
);
export const model = { name: '张三' };
v.pipe(
v.record(v.string(), v.string()),
formConfig({
groupKeySchema: v.picklist(['name', 'email', 'phone']),
groupValueSchema: v.pipe(v.string(), v.minLength(1)),
}),
);
键值对的完整用法见 Record Schema 动态对象组。
组里的子字段一个值都没有时,最终值取 emptyValue:
object-group-empty-value.definition.ts
import * as v from 'valibot';
import { formConfig, NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
profile: v.pipe(
v.object({
k1: v.optional(v.string()),
k2: v.optional(v.string()),
}),
formConfig({ emptyValue: { empty: true } }),
),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
export const model = { profile: {} };
profile 的两个子字段都是 v.optional() 且没有值,输出即为 emptyValue;填了任意一个子字段,输出就是正常的键值对象。