【问题标题】:Yup validate array of objects contains at most one object where property = value是的,验证对象数组最多包含一个对象,其中属性 = 值
【发布时间】:2020-10-15 05:50:58
【问题描述】:

我正在使用 Formik 的 FieldArray 将对象动态添加到数组中,将其他表单元素渲染为对象被 push()ed 到数组中。

我的架构如下所示:

const EMAIL_SCHEMA = Yup.object().shape({
  address: Yup.string().email().required( 'E-mail address is required.' ),
  isPreferredContact: Yup.boolean()
})

const SCHEMA = Yup.object().shape({
  emails: Yup.array()
             .of( EMAIL_SCHEMA )
             .ensure()
             .compact( v => !v.address )
             .required( 'At least one e-mail address is required.' )
})

对于每个电子邮件输入,都有一个对应的复选框来指示它是否是首选的联系人电子邮件地址。 不需要将电子邮件地址标记为首选。

我想做的是验证数组是否包含最多一个对象,其中isPreferredContacttrue。如果数组中有 3 个电子邮件对象并且isPreferredContact 对所有这些对象都是false,那么这是一个有效状态。也就是说:

let values = [
  {address: '1@email.com', isPreferredContact: false},
  {address: '2@email.com', isPreferredContact: false},
  {address: '3@email.com', isPreferredContact: false}
] // OK

let values = [
  {address: '1@email.com', isPreferredContact: true},
  {address: '2@email.com', isPreferredContact: false},
  {address: '3@email.com', isPreferredContact: false}
] // OK

let values = [
  {address: '1@email.com', isPreferredContact: true},
  {address: '2@email.com', isPreferredContact: true},
  {address: '3@email.com', isPreferredContact: false}
] // Invalid

我看到了这个答案

Yup: deep validation in array of objects

表明compact()方法可用于验证至少一个,因为如果从数组中删除“假”值后,数组为空,那么很容易处理架构键无效。

不过,我看不到任何东西来验证数组是否包含至多一个具有 property = value 谓词的对象。

有没有办法做到这一点?

【问题讨论】:

    标签: reactjs formik yup


    【解决方案1】:

    在 GitHub 中查看 Yup 的问题后,盯着 API 文档(addMethod 的文档真的很糟糕),并在代码沙箱中测试,我发现这是可行的:

    Yup.addMethod(Yup.array, 'atMostOne', function(args) {
      const { message, predicate } = args
      return this.test('atMostOne', message, function(list) {
        // If there are 2+ elements after filtering, we know atMostOne must be false.
        return list.filter(predicate).length < 2
      })
    })
    

    很明显,谓词是一个函数,它接受数组的一个元素并对其执行测试,返回一个boolean

    对于一个标量值数组,这就像el =&gt; el === value 一样简单。对于对象数组,它将是 el =&gt; el.property === valueel[property] === value

    希望这可以帮助其他对此感兴趣的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-07
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 2021-04-21
      • 1970-01-01
      相关资源
      最近更新 更多