本文介绍 Piying-View 如何处理 v.record() 类型的动态键值对表单。
record-group-overview.definition.ts
import * as v from 'valibot';
export const schema = v.object({
metadata: v.record(v.string(), v.string()),
});
export const model = { metadata: { department: '研发部', level: 'P7' } };
v.record(KeySchema, ValueSchema) 定义一个键为字符串、值为指定类型的对象。Piying-View 将 record 映射为特殊的 Group,键由用户动态添加:
record-basic.definition.ts
import * as v from 'valibot';
export const schema = v.object({
metadata: v.record(v.string(), v.string()),
scores: v.record(v.string(), v.number()),
});
export const model = { metadata: { k1: 'v1' }, scores: { s1: 1 } };
在 fieldGlobalConfig.types 中确保 record 有对应的容器组件:
options = {
fieldGlobalConfig: {
types: {
record: { type: PiyingViewGroup }, // 使用 Group 容器处理动态键
},
},
};
在表单场景中,Record 常用于:
record-label.definition.ts
import * as v from 'valibot';
export const schema = v.object({
labels: v.record(v.string(), v.string()),
});
export const model = { labels: { 研发部: 'P7' } };
用户可以动态添加键值对,如:{ "department": "研发部", "level": "P7" }。
record-config.definition.ts
import * as v from 'valibot';
export const schema = v.object({
config: v.record(v.string(), v.union([v.string(), v.number(), v.boolean()])),
});
export const model = { config: { theme: 'dark', count: 3 } };
record-translation.definition.ts
import * as v from 'valibot';
export const schema = v.object({
translations: v.record(v.picklist(['zh', 'en', 'ja', 'ko']), v.string()),
});
export const model = { translations: { zh: '你好' } };
FieldFormConfig 提供 groupKeySchema 和 groupValueSchema,用于约束 Record 的键和值类型:
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: '张三' };
注意:groupKeySchema 和 groupValueSchema 用于约束动态添加的键值对,而非替换原有的 record schema。
Record 字段的验证遵循标准 Group 规则:
record-validation.definition.ts
import * as v from 'valibot';
export const schema = v.object({
metadata: v.record(v.string(), v.pipe(v.number(), v.minValue(0))),
});
export const model = { metadata: { score: 5 } };
当 Record 中某个值不满足验证条件时,该键对应的子字段标记为错误,但不影响其他键的值。
record-complete.definition.ts
import * as v from 'valibot';
import { formConfig } from '@piying/view-angular-core';
export const schema = v.object({
metadata: v.record(v.string(), v.string()),
settings: v.pipe(
v.record(v.string(), v.boolean()),
formConfig({
groupKeySchema: v.picklist(['darkMode', 'notifications', 'autoSave']),
}),
),
teamMembers: v.record(
v.string(),
v.object({
name: v.string(),
role: v.string(),
}),
),
});
export const model = {
metadata: { k1: 'v1' },
settings: { darkMode: true },
teamMembers: { zhang: { name: '张三', role: '开发' } },
};