Antd关于Form踩的坑

836 阅读2分钟

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
}