Antd关于Form踩的坑
今天在开发时, 使用到了antd的自动验证表单功能, 很简单的一个操作, 比如说我绑定了一个Cascader组件
<Form.Item {...formItemLayout} label="Name">
{getFieldDecorator('username',
{
rules: [
{ required: true, message: 'Please input your name' }
]}
)(<Cascader options={options} onChange={onChange} placeholder="Please select"/>)}
上面是从官网拿到的例子, 比较简单,只是自动的拿到Cascadert的数据,进行必填判断 在rules中我们也可以增加第二个参数, 自定义验证规则validator
<Form.Item {...formItemLayout} label="Name">
{getFieldDecorator('username',
{
rules: [
{ required: true, message: 'Please input your name' } ,
{ validator: this.validator }
]}
)(<Cascader options={options} onChange={onChange} placeholder="Please select"/>)}
这个validator要传递一个函数的形式, 同时这个函数必须调用callback()方法,才能成功的进行校验 下面我们简单的写一个验证规则, 这个函数主要是用来判断级联选择时,该验证规则为判断是否选中所有可选地区, 若未选中则抛出异常, 此时根据antd组件级联选择可知value必须是一个数组的形式, 这时我们则可以直接判断value的长度来进行callback()回调错误提示
// value拿到的为当前组件所绑定的值, callback为当验证失败所抛出的提示异常
const validator = (rule: any, value: any, callback: any) => {
// 以下三行为公司中使用的枚举对象, 取到可以选择的地区信息, 就不展示具体代码了
const codeTable = codeMng.getCodeTable(this.props.codeTableName);
const items = codeTable.getItems();
const opts = toKeyTitle(items);
// 拿到第一层级的地区, 找到组件中选中的值与之相对应
const findFirst = opts.find((item: any) => item.value === value[0]);
// 当找到时, 自动判断是否有子级地区, 如果有则判断组件的值数量是否小于2, 小于2时
// 抛出异常
if(findFirst.children && value.length < 2) {
callback('请选择剩下的选项')
return
}
// 拿到第二层级的地区, 找到组件中index为1选中的值与之相对应
const findSecond = findFirst.children.find((item: any) => item.value === value[1])
// 当找到时, 自动判断是否有子级地区, 如果有则判断组件的值数量是否小于3, 小于3时
// 抛出异常
if(findSecond.children && value.length < 3) {
callback('请选择剩下的选项')
return
}
callback()
return
}
}
但是这里要注意, 如果我们此时还没有任何的选项时, value为null, 但是奇怪的是在第五行的代码中调用null[0]并不会进行报错提示, 导致阻塞了后面的所有代码, 导致自动表单失效. 我们在开发时要做好边界处理, 在最开始应该进行value为空的判断
const validator = (rule: any, value: any, callback: any) => {
if(value) {
const codeTable = codeMng.getCodeTable(this.props.codeTableName);
const items = codeTable.getItems();
const opts = toKeyTitle(items);
const findFirst = opts.find((item: any) => item.value === value[0]);
if(findFirst.children && value.length < 2) {
callback('请选择剩下的选项')
return
}
const findSecond = findFirst.children.find((item: any) => item.value === value[1])
if(findSecond.children && value.length < 3) {
callback('请选择剩下的选项')
return
}
}
callback()
return
}