You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Ant Design的动态表单:隐藏数据库空值表单项与模态框表单重置实现问询

解决方案:处理空值表单项与表单重置问题

我来帮你搞定这两个问题,咱们分两步走:

1. 过滤数据库返回的空值表单项

数据库里的全空条目会被Form.List直接渲染出来,所以第一步要先把这些无意义的空条目过滤掉。我们需要在组件内部对传入的questionData做预处理,只保留有实际内容的题目部分;要是过滤后没有有效条目,就留一个空的默认项用来添加新内容。

2. 模态框打开时强制重置表单

现在你只在关闭模态框时重置表单,但打开的时候也需要重新初始化,确保每次打开都是干净的状态,不会残留之前的空条目或旧数据。

修改后的完整组件代码

import { useEffect } from 'react';
import { Modal, Form, Input, Space, Row, Col, Button, MinusCircleOutlined, PlusOutlined } from 'antd';
import { useDispatch } from 'react-redux';

const AddPartQuestionModalAgain = ({ 
  isModalVisible, 
  hideModal, 
  questionData = { 
    question_no: '', 
    question_parts: [{ 
      part_desc: '', 
      part_total_marks: '', 
      part_guided_answer: [{ part_model_ans: '', part_answer_mark: '' }] 
    }], 
  }, 
}) => { 
  const dispatch = useDispatch(); 
  let formInput;

  // 监听模态框显示状态,打开时重置并初始化表单
  useEffect(() => {
    if (isModalVisible && formInput) {
      // 过滤全空的question_parts条目
      const cleanedQuestionParts = questionData.question_parts.filter(part => {
        // 检查当前题目部分的核心字段是否全为空
        const isPartEmpty = 
          (part.part_desc == null || part.part_desc.trim() === '') &&
          (part.part_total_marks == null || part.part_total_marks.trim() === '');
        
        // 检查该部分的引导答案是否全为空
        const isGuidedAnswersEmpty = !part.part_guided_answer || 
          part.part_guided_answer.every(ans => 
            (ans.part_model_ans == null || ans.part_model_ans.trim() === '') &&
            (ans.part_answer_mark == null || ans.part_answer_mark.trim() === '')
          );

        // 只要有一个字段有内容,就保留该条目
        return !(isPartEmpty && isGuidedAnswersEmpty);
      });

      // 如果过滤后没有条目,设置一个空的默认题目部分
      const finalQuestionParts = cleanedQuestionParts.length > 0 
        ? cleanedQuestionParts 
        : [{ part_desc: '', part_total_marks: '', part_guided_answer: [{ part_model_ans: '', part_answer_mark: '' }] }];

      // 重置表单并设置处理后的初始值
      formInput.resetFields();
      formInput.setFieldsValue({
        ...questionData,
        question_parts: finalQuestionParts
      });
    }
  }, [isModalVisible, questionData]);

  return ( 
    <> 
      <Modal 
        visible={isModalVisible} 
        onCancel={() => { 
          formInput.resetFields(); 
          hideModal(); 
        }} 
        width={1200}
        footer={[
          <Button key="back" onClick={() => {
            formInput.resetFields();
            hideModal();
          }}>
            取消
          </Button>,
          <Button key="submit" type="primary" onClick={() => {
            formInput.validateFields().then(values => {
              console.log('提交的数据:', values);
              // 这里替换成你的提交逻辑,比如dispatch action
              hideModal();
            }).catch(errorInfo => {
              console.log('表单验证失败:', errorInfo);
            });
          }}>
            确认提交
          </Button>,
        ]}
      > 
        <Form 
          layout='vertical' 
          ref={(ref) => { formInput = ref }} 
          name='dynamic_form_item'
        > 
          <Form.List name='question_parts' key='question_parts'> 
            {(fields, { add, remove }, { errors }) => ( 
              <> 
                {fields.map((field, index) => ( 
                  <Space key={field.key} direction='vertical' > 
                    <Form.Item key={`QuestionPart${index}`}> 
                      <Row> 
                        <Col span={10}> 
                          <div style={{ overflow: 'auto', height: 400, width: 590, }} > 
                            <Form.Item 
                              {...field} 
                              label={`Question Part ${index + 1} Description`} 
                              fieldKey={[field.fieldKey, 'part_desc']} 
                              name={[field.name, 'part_desc']} 
                              key={`part_desc${index}`}
                              rules={[{ required: true, message: '请输入题目描述' }]}
                            > 
                              <Input.TextArea rows={8} placeholder='Description' /> 
                            </Form.Item> 
                            <Form.Item 
                              {...field} 
                              label={`Question Part ${index + 1} Marks`} 
                              fieldKey={[field.fieldKey, 'part_total_marks']} 
                              name={[field.name, 'part_total_marks']} 
                              key={`part_total_marks${index}`}
                              rules={[{ required: true, message: '请输入分数', type: 'number' }]}
                            > 
                              <Input placeholder='Marks' style={{ border: '1px solid black', width: 450, }} /> 
                            </Form.Item> 
                          </div> 
                        </Col> 
                        <div className='vl'></div> 
                        <Col span={12} offset={2}> 
                          <div > 
                            <Form.List 
                              {...field} 
                              name='part_guided_answer' 
                              fieldKey={[field.fieldKey, 'part_guided_answer']} 
                              key={`part_guided_answer${index}`} 
                            > 
                              {(fields, { add, remove }, { errors }) => ( 
                                <> 
                                  {fields.map((field, idx) => ( 
                                    <Space key={field.key} direction='vertical' > 
                                      <Form.Item key={`QuestionPartGuided${idx}`}> 
                                        <Form.Item 
                                          {...field} 
                                          label={`Question Part Guided Answer ${idx + 1}`} 
                                          fieldKey={[field.fieldKey, 'part_model_ans']} 
                                          name={[field.name, 'part_model_ans']} 
                                          key={`part_model_ans${idx}`}
                                          rules={[{ required: true, message: '请输入引导答案' }]}
                                        > 
                                          <Input.TextArea rows={4} placeholder='Guided Answer' /> 
                                        </Form.Item> 
                                        <Form.Item 
                                          {...field} 
                                          label={`Question Part Guided Answer Marks ${idx + 1}`} 
                                          fieldKey={[field.fieldKey, 'part_answer_mark']} 
                                          name={[field.name, 'part_answer_mark']} 
                                          key={`part_answer_mark${idx}`}
                                          rules={[{ required: true, message: '请输入引导答案分数', type: 'number' }]}
                                        > 
                                          <Input placeholder='Guided Answer Marks' /> 
                                        </Form.Item> 
                                        <MinusCircleOutlined 
                                          className='dynamic-delete-button' 
                                          onClick={() => remove(field.name)} 
                                        /> 
                                      </Form.Item> 
                                    </Space> 
                                  ))} 
                                  <Form.Item style={{ fontWeight: 'bold' }}> 
                                    <Button type='dashed' onClick={() => add()} icon={<PlusOutlined />} > 
                                      Add Question Part Guided Answer 
                                    </Button> 
                                    <Form.ErrorList errors={errors} /> 
                                  </Form.Item> 
                                </> 
                              )} 
                            </Form.List> 
                          </div> 
                        </Col> 
                        <MinusCircleOutlined 
                          className='dynamic-delete-button' 
                          onClick={() => remove(field.name)} 
                        /> 
                      </Row> 
                      <div className='vr'></div> 
                    </Form.Item> 
                  </Space> 
                ))} 
                <Form.Item> 
                  <Button type='dashed' onClick={() => add()} icon={<PlusOutlined />} > 
                    Add Question Part 
                  </Button> 
                  <Form.ErrorList errors={errors} /> 
                </Form.Item> 
              </> 
            )} 
          </Form.List> 
        </Form> 
      </Modal> 
    </> 
  ) 
};

export default AddPartQuestionModalAgain;

关键修改点说明

  1. 空值过滤逻辑:在useEffect里对question_parts进行过滤,只有当题目部分的描述、分数,或者其下的引导答案至少有一个有内容时,才保留该条目。
  2. 表单重置与初始化:监听isModalVisible的变化,当模态框打开时,先重置表单再设置过滤后的初始值,确保每次打开都是干净的状态。
  3. 完善默认值结构:把questionData的默认question_parts从['']改成符合实际结构的对象数组,避免类型不匹配导致的渲染问题。
  4. 添加表单验证:给必填字段加上验证规则,防止用户提交空内容。

内容的提问来源于stack exchange,提问作者IDon'tGetIt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 17:42:31