美文网首页
需求:使用 rc-form 在一个大的页面中包含多个Form,验

需求:使用 rc-form 在一个大的页面中包含多个Form,验

作者: 日不落000 | 来源:发表于2020-01-11 19:48 被阅读0次

    需求:使用 rc-form 在一个大的页面中包含多个Form,验证如果有报错那么滚动到报错位置

    首先说明一下,是不推荐这样做的,因为之前代码是这样的了,在平衡后期维护成本和代码优雅性等方面后,决定着手解决这个问题。

    推荐尽量开发前期规划好,用一个Form处理整个表单,可以将一个大的Form分割为多个方法组件,放到不同的文件中,这样如果有报错滚动到报错位置会比较简单,单个文件也不会太大。
    目前问题代码示例如下:

    index.js render 中

                  <BasicInfo
                    {...basicInfo}
                    errorFlag={errorFlag}
                    onChange={this.handleFormChange}
                  />
    
    

    BasicInfo.js

    import React from 'react';
    import { Form, Input, Popover, Select, Icon } from 'antd';
    import messages from './messages';
    
    const { Option } = Select;
    
    const BasicInfo = Form.create({
      name: 'basicInfo',
      onFieldsChange(props, changedFields) {
        props.onChange(changedFields);
      },
      mapPropsToFields(props) {
        return {
          name: Form.createFormField({
            ...props.name,
            value: props.name && props.name.value,
          }),
      },
    })((props) => {
      const { errorFlag, intl, form: { getFieldDecorator }, } = props;
      return (
        <Form
          hideRequiredMark
          className="rt-create-common-paddingLeft"
        >
          <div className={`rt-line-flex ${errorFlag ? 'has-error' : ''}`} style={{ alignItems: 'center' }}>
            <Form.Item label={intl.formatMessage(messages.Name)}>
              {getFieldDecorator('name', {
              })(<Input style={{ width: 302, marginRight: '16px' }} autoComplete="off" />)}
            </Form.Item>
            {
              errorFlag && (
                <div className="ant-form-explain rt-position-errors">{intl.formatMessage(messages.Cannotbeempty)}</div>
              )
            }
          </div>
        </Form>
      );
    });
    export default BasicInfo;
    
    
    解决思路以及过程如下:

    先检查了BasicInfo的ref如下:

                  <BasicInfo
                    ref={(ref)=>{
                      this.refBasicInfo = ref;
                      console.log('this.refBasicInfo',this.refBasicInfo);
                    }}
                    {...basicInfo}
                    errorFlag={errorFlag}
                    onChange={this.handleFormChange}
                  />
    

    看到了关键的方法 validateFieldsAndScroll


    image.png

    接下来看这个方法是否生效,添加如下代码

    //点击按钮滚动到期望的报错位置
      handleClick = () => {
        if(this.refBasicInfo){
          this.refBasicInfo.validateFieldsAndScroll(async (err, values) => {
            console.log('this.refBasicInfo.validateFieldsAndScroll',err, values);
          })
        }
        return ;
    }
    

    当点击按钮的时候报错位置的确滚动到了当前视野范围内,但是我们的项目顶部有一个导航栏把关键的报错位置刚刚好挡住了,所以想要让报错位置滚动到导航栏下方100px处,所以去查看了文档antd Form validateFieldsAndScroll 方法的使用方法和参数如下:


    image.png image.png

    看到如上内容后改动代码为:

    //点击按钮滚动到期望的报错位置
      handleClick = () => {
    
        if(this.refBasicInfo){
          this.refBasicInfo.validateFieldsAndScroll({
    /**
    这里可以添加force字段强制校验,对已经校验过的表单域,在 validateTrigger 再次被触发时是否再次校验;
    可以传想传的任何参数过去,在自定义的validator中接收options,
      const toValidate = (rule, value, callback, source, options) => {
        if (options.hasError) {
          callback(' ');
        } else {
          callback();
        }
      };
    */
    
            scroll :{
              offsetTop: 100,
              onlyScrollIfNeeded: true,
              allowHorizontalScroll: false,
            }
          },async (err, values) => {
            console.log('this.refBasicInfo.validateFieldsAndScroll',err, values);
          })
        }
        return ;
    }
    

    实现了预期的效果。
    其他的多个form可以类似处理,依次判断即可。

    参考:

    https://ant.design/components/form-cn/#components-form-demo-validate-static

    https://github.com/yiminghe/dom-scroll-into-view#function-parameter

    相关文章

      网友评论

          本文标题:需求:使用 rc-form 在一个大的页面中包含多个Form,验

          本文链接:https://www.haomeiwen.com/subject/jbjbactx.html