【问题标题】:Create Yup nested object schema dynamically动态创建 Yup 嵌套对象模式
【发布时间】:2019-09-13 17:50:01
【问题描述】:

对于这个“平面”对象验证

const fields = [
  {label: 'Name', name: 'name', validation: yup.string().required()},
  {label: 'City', name: 'city', validation: yup.string().required()},
  {label: 'Phone', name: 'phone'},
]

我创建了createYupSchema 函数来从fields 获取Yup 模式对象。

const createYupSchema = (fields ) => {
  const schema = fields.reduce((schema, field) => {
      return field.validation 
      ? {...schema, [field.name]: field.validation} 
      : schema
  }, {})

  return yup.object().shape(schema)
}

输出是 Yup 对象:

yup.object().shape({
  name: yup.string().required(),
  city: yup.string().required(),
}) 

但我也可以在 fields 中使用嵌套对象

const fields = [
  {label: 'Name', name: 'name', validation: yup.string().required()},
  {label: 'Address', name: 'address.city', validation: yup.string().required()},
  {label: 'Phone', name: 'phone'},
]

所以 Yup 对象应该是:

yup.object().shape({
  name: yup.string().required(),
  address: yup.object().shape({
      city: yup.string().required()
  }),
}) 

是否可以从fields 创建这种类型的 Yup 对象?

【问题讨论】:

    标签: javascript formik yup


    【解决方案1】:

    我解决了我的问题。现在createYupSchema 就是这样工作的

    const createYupSchema = fields => {
      const schema = fields.reduce((schema, field) => {
        const isObject = field.name.indexOf(".") >= 0;
    
        if (!field.validation) {
          return schema;
        }
    
        if (!isObject) {
          return { ...schema, [field.name]: field.validation };
        }
    
        const reversePath = field.name.split(".").reverse();
        const currNestedObject = reversePath .slice(1).reduce((yupObj, path) => {
            return { [path]: yup.object().shape(yupObj) };
        }, {[reversePath [0]]: field.validation});
    
        return { ...schema, ...currNestedObject };
      }, {});
    
      return yup.object().shape(schema);
    };
    

    【讨论】:

      【解决方案2】:

      我用“懒惰”的方法解决了我的问题:

      const validateSchema = Yup.object().shape({
          items: Yup.array().of(
              Yup.lazy((item) => {
                  return Yup.object({
                      itemName: Yup.string().test(
                          'validate',
                          'warning',
                          (value) => {
                              if (value && item.itemDescription) return true
                              if (!value && !item.itemDescription) return true
                              return false
                          }
                      ),
                      itemDescription: Yup.string().test(
                          'validate',
                          'warning',
                          (value) => {
                              if (value && item.itemName) return true
                              if (!value && !item.itemName) return true
                              return false
                          }
                      ),
                  })
              })
          ),
      })
      

      【讨论】:

      • 请下次解释你提供的代码,提供代码片段或修复 OP 并没有帮助他或让他了解错误是什么以及如何修复它
      • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      • 1970-01-01
      • 2019-04-13
      • 2014-04-29
      • 2016-09-09
      • 2017-01-06
      相关资源
      最近更新 更多