繁体   English   中英

使用Joi和/或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编写的,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()
    })
})

我需要相同的可选地址检查:与其对照每个其他地址字段检查每个字段,不如在表单/模式中设置一个名为“ addressStarted”的标志,然后将其用作when触发器。 在我的情况下,标志是用户的明确选择,但也可以很容易地将其作为隐藏值。 只需在每个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()
  }),
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM