使用 Joi and/or Yup 进行模式验证,如果存在任何其他属性,是否有办法制作所需属性的集合?
Using Joi and/or Yup for schema validation, is there a way to make a collection of properties required if any of the other properties are present?
以收集个人详细信息的 HTML 表格为例。
注意:代码片段经过简化,与屏幕截图不完全匹配。此外,代码片段是使用 Yup 编写的,它是一个与 Joi 非常相似的库,它针对浏览器而不是 NodeJS。
为了提交表单,我想 运行 验证地址字段并将其设为必填,但前提是用户已部分填写地址部分。总的来说,我想将地址详细信息设为可选。
这是我的 PersonSchema 的简化版本...
import { object, string, number } from 'yup'
const PersonSchema = object().shape({
name: string().required(),
age: number()
.positive()
.integer()
.required(),
address: AddressSchema
})
以这种方式定义 AddressSchema 不起作用,因为字段始终是必需的...
const AddressSchema = object().shape({
street: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
city: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
state: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required()
})
这里是我尝试使地址字段依赖于其他地址字段的存在,但这不起作用,因为你 运行 陷入循环依赖问题...
const AddressSchema = object().shape({
street: string()
.when(['city', 'state'], {
is: (city, state) => city || state,
then: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
otherwise: string()
}),
city: string()
.when(['street', 'state'], {
is: (street, state) => street || state,
then: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
otherwise: string()
}),
state: string()
.when(['street', 'city'], {
is: (street, city) => street || city,
then: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
otherwise: string()
})
})
我需要相同的可选地址检查:与其根据每个其他地址字段检查每个字段,只需在您的 form/schema 中设置一个标志,命名为 'addressStarted',然后将其用作您的当触发。在我的案例中,该标志是用户的明确选择,但它也可以很容易地成为隐藏值;只需在每个 onChange 处理程序中将值切换为 true(如果您使用的是 Formik 之类的东西),或者甚至只是包含所有地址字段的元素上的事件侦听器。
import { object, string, number } from 'yup'
const AddressSchema = object().shape({
street: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
city: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
state: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required()
})
const PersonSchema = object().shape({
name: string().required(),
age: number()
.positive()
.integer()
.required(),
addressStarted: Yup.boolean(),
address: object().when('addressStarted', {
is: true,
then: AddressSchema,
otherwise: object().notRequired()
}),
})
以收集个人详细信息的 HTML 表格为例。
注意:代码片段经过简化,与屏幕截图不完全匹配。此外,代码片段是使用 Yup 编写的,它是一个与 Joi 非常相似的库,它针对浏览器而不是 NodeJS。
为了提交表单,我想 运行 验证地址字段并将其设为必填,但前提是用户已部分填写地址部分。总的来说,我想将地址详细信息设为可选。
这是我的 PersonSchema 的简化版本...
import { object, string, number } from 'yup'
const PersonSchema = object().shape({
name: string().required(),
age: number()
.positive()
.integer()
.required(),
address: AddressSchema
})
以这种方式定义 AddressSchema 不起作用,因为字段始终是必需的...
const AddressSchema = object().shape({
street: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
city: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
state: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required()
})
这里是我尝试使地址字段依赖于其他地址字段的存在,但这不起作用,因为你 运行 陷入循环依赖问题...
const AddressSchema = object().shape({
street: string()
.when(['city', 'state'], {
is: (city, state) => city || state,
then: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
otherwise: string()
}),
city: string()
.when(['street', 'state'], {
is: (street, state) => street || state,
then: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
otherwise: string()
}),
state: string()
.when(['street', 'city'], {
is: (street, city) => street || city,
then: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
otherwise: string()
})
})
我需要相同的可选地址检查:与其根据每个其他地址字段检查每个字段,只需在您的 form/schema 中设置一个标志,命名为 'addressStarted',然后将其用作您的当触发。在我的案例中,该标志是用户的明确选择,但它也可以很容易地成为隐藏值;只需在每个 onChange 处理程序中将值切换为 true(如果您使用的是 Formik 之类的东西),或者甚至只是包含所有地址字段的元素上的事件侦听器。
import { object, string, number } from 'yup'
const AddressSchema = object().shape({
street: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
city: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required(),
state: string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required()
})
const PersonSchema = object().shape({
name: string().required(),
age: number()
.positive()
.integer()
.required(),
addressStarted: Yup.boolean(),
address: object().when('addressStarted', {
is: true,
then: AddressSchema,
otherwise: object().notRequired()
}),
})