不渲染的Form.Item提交时如何触发校验

2022-09-19  本文已影响0人  景阳冈大虫在此

问题描述

我的页面用antd的Form写的,如下:


页面的部分样子

在渲染的时候大部分Form.Item不会被渲染出来。这在使用的时候倒是没什么问题,但是到了提交的时候,因为Form.Item没有渲染,哪怕未选中的那些项有错误的值,也因为没有触发校验而顺利提交了。

当然,下下策是最后提交的时候手动遍历数组然后自己写校验代码也可以,但是这极不灵活而且一定程度上失去了使用Form的意义——我用它不就是干这个的吗,那校验我又自己重写了,用它干嘛。

问了一下身边的人,答曰,你让他全部渲染出来不就好了。
……
在不短的沉默后,我们都笑了。

尝试

我知道多节点渲染的优化解决方案里就有虚拟滚动,就是只渲染需要展示的节点。
但是我很好奇这个页面全部渲染的情况下能有多卡。
数据如下:


节点全部渲染后,点击新增按钮的性能数据

就算不看数据,就是随便做一个操作感觉上就像一个世纪那么漫长。
所以我还是改回来了。


目前的方案,点击新增按钮的性能数据

解决

我想到一个好办法。
提交的时候覆盖上一个蒙层,弄一个loading告诉用户在校验中。
然后依次去选中,然后每次选完了就去调用form.validateFields()
如果出错了,刚好停下来,让用户去改错误。
代码

  const onFinishFailed = ({ errorFields }) => {
    if (errorFields?.length) {
      errorFields.forEach(
        (cur) => cur?.errors[0] && message.error(cur?.errors[0]),
      );
    }
  };

  const clickEveryPlayCheckError = async (values, curIndex = 0) => { // 依次点击,依次校验,发现有错误就停下来报错
    if (values?.playSteps?.length <= curIndex) return true;
    console.log('submit validating...', curIndex);
    editPlayRef?.current?.updateActiveItem(values?.playSteps[curIndex]); // 更换当前展示的item
    await new Promise((resolve) => setTimeout(resolve, 10));
    try {
      await form.validateFields();
      return clickEveryPlayCheckError(values, 1 + curIndex);
    } catch (error) {
      console.log('err', error);
      onFinishFailed(error);
    }
    return false;
  };

  const onFinish = async (values) => {
    console.log("submit", values); // eslint-disable-line
    setSubmitValidating(true);
    const validateRes = await clickEveryPlayCheckError(values);
    setSubmitValidating(false);
    if (!validateRes) return;
// ……
}

效果如下


提交校验效果
上一篇下一篇

猜你喜欢

热点阅读