是的,验证对象数组最多包含一个对象,其中 属性 = value
Yup validate array of objects contains at most one object where property = value
我正在使用 Formik 的 FieldArray
将对象动态添加到数组,当对象被 push()
编辑到数组时呈现额外的表单元素。
我的架构如下所示:
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.' )
})
对于每个电子邮件输入,都有一个相应的复选框来指示它是否是首选的联系电子邮件地址。 不需要 将电子邮件地址标记为首选。
我想做的是验证数组包含 至多一个 对象,其中 isPreferredContact
是 true
。如果数组中有 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()
方法可用于验证 至少一个 ,因为如果从数组中删除“虚假”值后,数组为空,那么很容易将架构键视为无效。
不过,我看不到任何东西来验证数组是否包含 至多 一个具有 属性 = 值谓词的对象。
有办法吗?
在 GitHub 中查看 Yup 的问题后,盯着 API 文档(addMethod
的文档真的很糟糕),并在 Code Sandbox 中进行测试后,我发现这个作品:
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
})
})
显然,谓词是一个函数,它接受数组的一个元素并对其执行测试 returns a boolean
.
对于标量值数组,这与 el => el === value
一样简单。对于对象数组,它将是 el => el.property === value
或 el[property] === value
.
希望这对其他对此好奇的人有所帮助。
我正在使用 Formik 的 FieldArray
将对象动态添加到数组,当对象被 push()
编辑到数组时呈现额外的表单元素。
我的架构如下所示:
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.' )
})
对于每个电子邮件输入,都有一个相应的复选框来指示它是否是首选的联系电子邮件地址。 不需要 将电子邮件地址标记为首选。
我想做的是验证数组包含 至多一个 对象,其中 isPreferredContact
是 true
。如果数组中有 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()
方法可用于验证 至少一个 ,因为如果从数组中删除“虚假”值后,数组为空,那么很容易将架构键视为无效。
不过,我看不到任何东西来验证数组是否包含 至多 一个具有 属性 = 值谓词的对象。
有办法吗?
在 GitHub 中查看 Yup 的问题后,盯着 API 文档(addMethod
的文档真的很糟糕),并在 Code Sandbox 中进行测试后,我发现这个作品:
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
})
})
显然,谓词是一个函数,它接受数组的一个元素并对其执行测试 returns a boolean
.
对于标量值数组,这与 el => el === value
一样简单。对于对象数组,它将是 el => el.property === value
或 el[property] === value
.
希望这对其他对此好奇的人有所帮助。