【问题标题】:React/AntDesign Trigger Form.Item Re-Validation on EventReact/AntDesign Trigger Form.Item Re-Validation on Event
【发布时间】:2021-11-04 23:16:07
【问题描述】:

问题背景

我正在使用功能组件内的 AntDesign 表单收集用户输入。用户必须观看视频剪辑并确定视频中某些事件发生的相对时间段,包括“开始时间”和“结束时间”,格式为 (HH:MM:SS) - (HH:MM:SS ),例如 00:05:30 - 00:05:35(5 秒时间段)。

收集此数据的表单由两个

组成。一个收集开始时间,另一个收集结束时间。 (对于如何构造表单还有其他情况,因此在这种情况下,Form.Items 作为 JSX 返回,以包装在 render 方法中的 Form 中。)像这样:
const timeInput = () => {
    return (
        <>
        <Form.Item
            name={"start-time"}
            hasFeedback
            rules={[
                {
                    required: true,
                    message: 'Required',
                },
                ({ getFieldValue }) => ({
                    validator(_, value) {
                        return startTimeInputValidator(getFieldValue, "end-time", value)
                    }
                })
            ]}
        >
        <Input 
        id="start-time-input"
        placeholder={"Start Time (HH:MM:SS)"} />
        </Form.Item>

        <Form.Item
            name={"end-time"}
            hasFeedback
            rules={[
                {
                    required: true,
                    message: 'Required',
                },
                ({ getFieldValue }) => ({
                    validator(_, value) {
                        return endTimeInputValidator(getFieldValue, "start-time", value)
                    }
                })
            ]}
        >
        <Input 
        id="end-time-input"
        placeholder={"End Time (HH:MM:SS)"} />
        </Form.Item>
        </>
    )        
}

每个表单项的输入都使用从单独文件导入的自定义验证器进行验证:

const regexTime = /^(?:[01]\d|2[0123]):(?:[012345]\d):(?:[012345]\d)$/;
const timeInvalidDesc = "Not a Valid Time!";
const doStartTimeDesc = "Start Time Invalid!";
const timeMismatchDesc = "End Time must be after Start Time!";

export async function startTimeInputValidator(getFieldValue, field, text) {
    var endTime = getFieldValue(field);
    if (!text) {
        return Promise.resolve();
    }
    if(text.length<8) {
        return Promise.reject();
    }
    if (!regexTime.test(text)) {
        return Promise.reject(new Error(timeInvalidDesc));
    }
    if(regexTime.test(endTime)) {
        let stn = timeToInt(text);
        let etn = timeToInt(endTime);
        if(stn > etn) {
            return Promise.reject(new Error(timeMismatchDesc));
        }
    }
    return Promise.resolve();
}

export async function endTimeInputValidator(getFieldValue, field, text) {
    var startTime = getFieldValue(field);
    if (!text) {
        return Promise.resolve();
    }
    if(text.length<8) {
        return Promise.reject();
    }
    if (!regexTime.test(text)) {
        return Promise.reject(new Error(timeInvalidDesc));
    }
    if (!regexTime.test(startTime)) {
        return Promise.reject(new Error(doStartTimeDesc));
    }
    let stn = timeToInt(startTime);
    let etn = timeToInt(text);
    if(stn > etn) {
        return Promise.reject(new Error(timeMismatchDesc));
    }
    return Promise.resolve();
}

验证器正确地确保用户以 'HH:MM:SS' 形式输入了有效时间,并且它们还正确地确保了 'end-time' 不早于 'start-time',即如果“结束时间”在“开始时间”之前,则无法提交表单,因为我假设当用户提交表单时,这些字段会重新验证。

当用户出现问题时:

  1. 输入有效的“开始时间”(不完整的表格)
    • 例如:00:00:05 - null
  2. 输入有效的“结束时间”(有效的完整表格)
    • 例如:00:00:05 - 00:00:10
  3. 将“开始时间”更改为“结束时间”之后(无效的完整表格)
    • 例如:00:00:15 - 00:00:10
  4. 将“结束时间”更改为新的“开始时间”之后(应该是有效的完整表格)
    • 例如:00:00:15 - 00:00:20

现在,在上述情况下,鉴于输入有效且时间顺序正确,表单不应显示错误消息,但仍会显示开始时间字段的错误消息,因为在第 4 步期间'start-time' 的验证器没有被触发。

问题

我的问题归结为:当“结束时间”输入发生更改(反之亦然)时,如何重新验证“开始时间”,以响应更新错误消息作为用户改变他们的输入?换句话说,当任何一个的输入发生更改时,如何验证 both Form.Items?

如果我花了太长时间才找到问题的核心,我深表歉意。我认为太多的上下文总比太少好。提前谢谢你。

【问题讨论】:

    标签: javascript reactjs antd


    【解决方案1】:

    你应该设置字段“end-time”的依赖属性
    文档:https://ant.design/components/form/#dependencies

    【讨论】:

      猜你喜欢
      • 2014-02-12
      • 2021-02-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-15
      • 2019-04-20
      • 2019-01-13
      • 1970-01-01
      相关资源
      最近更新 更多