Antd ProComponents中的EditableProTable无法在子行继续新增子行的解决方案

 更新时间:2022年08月02日 10:18:19   作者:曲鸟  
这篇文章主要介绍了Antd ProComponents中的EditableProTable无法在子行继续新增子行的解决方案,本文通过复现代码给大家详细讲解,需要的朋友可以参考下

一、BUG效果如下

点击后报错:

二、复现代码

import { EditableProTable } from '@ant-design/pro-table';
import React, { useState } from 'react';

const defaultData: any = new Array(3).fill(1).map((_, index) => {
  return {
    id: (Date.now() + index).toString(),
    title: `活动名称${index}`,
    decs: '这个活动真好玩',
    state: 'open',
    created_at: '2020-05-26T09:42:56Z',
  };
});

export default () => {
  const [editableKeys, setEditableRowKeys] = useState<React.Key[]>(() =>
    defaultData.map((item) => item.id),
  );
  const [dataSource, setDataSource] = useState<any[]>(() => defaultData);

  const columns: any = [
    {
      title: '活动名称',
      dataIndex: 'title',
      width: '30%',
      formItemProps: {
        rules: [
          {
            required: true,
            whitespace: true,
            message: '此项是必填项',
          },
          {
            message: '必须包含数字',
            pattern: /[0-9]/,
          },
          {
            max: 16,
            whitespace: true,
            message: '最长为 16 位',
          },
          {
            min: 6,
            whitespace: true,
            message: '最小为 6 位',
          },
        ],
      },
    },
    {
      title: '状态',
      key: 'state',
      dataIndex: 'state',
      valueType: 'select',
      valueEnum: {
        all: { text: '全部', status: 'Default' },
        open: {
          text: '未解决',
          status: 'Error',
        },
        closed: {
          text: '已解决',
          status: 'Success',
        },
      },
    },
    {
      title: '描述',
      dataIndex: 'decs',
    },
    {
      title: '操作',
      valueType: 'option',
      width: 250,
      render: () => {
        return null;
      },
    },
  ];

  return (
    <>
      <EditableProTable<any>
        headerTitle="可编辑表格"
        columns={columns}
        rowKey="id"
        scroll={{
          x: 960,
        }}
        value={dataSource}
        onChange={setDataSource}
        recordCreatorProps={{
          newRecordType: 'dataSource',
          position: 'bottom',
          record: () => ({
            id: Date.now(),
          }),
        }}
        editable={{
          type: 'multiple',
          editableKeys,
          actionRender: (row, config, defaultDoms) => {
            return [defaultDoms.delete,
            <EditableProTable.RecordCreator
              parentKey={row.id}
              newRecordType='dataSource'
              position='bottom'
              record={{
                id: Date.now(),
              }}
            >
              <a>增加子行</a>
            </EditableProTable.RecordCreator>];
          },
          onValuesChange: (record, recordList) => {
            setDataSource(recordList);
          },
          onChange: setEditableRowKeys,
        }}
      />
    </>
  );
};

三、解决方案

自己写一个递归的方法将子行追加到选中行下即可,下面展示的是我项目中的代码,不能复制直接用,但思路是一样的。
首先在actionRender中自定义“增加子行”的操作按钮,其中addChildToSource为增加逻辑方法:

       actionRender: (row, _, dom) => [
            <a
              key="addChild"
              onClick={() => addChildToSource(row.id, type)}
            >
              增加子行
            </a>
          ],

addChildToSource代码如下:

  //增加子行
  const addChildToSource = (rowKey: any, type: string) => {
    let childRowKey = Date.now(); //rowkey的id不能重复,不然会回填异常
    editableKeys[type].push(childRowKey);
    let source = formRef.current.getFieldValue(`${type}_source`); //type_source为表格定义的formItem的name
    source = addChildToSourceFunc(source, rowKey, childRowKey, type);
    const _dict = {};
    _dict[`${type}_source`] = source;
    formRef.current.setFieldsValue(_dict);
    setEditableKeys({ ...editableKeys });
  };

上述方法调用的addChildToSourceFunc代码如下:

  //删除参数edit及子级edit
   const addChildToSourceFunc = (
    source: any,
    rowKey: any,
    childRowKey: any,
    type: string,
    childName: any = null,
  ) => {
    for (var i = 0; i < source.length; i++) {
      const sourceItem = source[i];
      if (sourceItem.id === rowKey) {
        if (!sourceItem.children) {
          sourceItem.children = [];
        }
        sourceItem.children.push({ id: childRowKey, required: true, param_type: 'string', name: childName });
        break;
      } else if (sourceItem.children) {
        addChildToSourceFunc(sourceItem.children, rowKey, childRowKey, type, childName,);
      }
    }
    return source;
  };

成功解决了该问题,解决后的效果:

到此这篇关于Antd ProComponents中的EditableProTable无法在子行继续新增子行的解决方案的文章就介绍到这了,更多相关Antd ProComponents子行内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用eslint和githooks统一前端风格的技巧

    使用eslint和githooks统一前端风格的技巧

    这篇文章主要介绍了使用eslint和githooks统一前端风格,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • JS创建Tag标签的方法详解

    JS创建Tag标签的方法详解

    这篇文章主要介绍了JS创建Tag标签的方法,结合具体实例形式分析了javascript动态操作页面HTML元素实现tag标签功能的步骤与相关操作技巧,需要的朋友可以参考下
    2017-06-06
  • js实现日历

    js实现日历

    这篇文章主要介绍了js如何实现日历,帮助大家完成需求,提高对js的理解,感兴趣的朋友可以了解下
    2020-11-11
  • js实现兼容IE6与IE7的DIV高度

    js实现兼容IE6与IE7的DIV高度

    兼容IE6与IE7的DIV高度的js代码,
    2010-05-05
  • Bootstrap笔记之缩略图、警告框实例详解

    Bootstrap笔记之缩略图、警告框实例详解

    本文通过实例给大家详解介绍了Bootstrap笔记之缩略图、警告框知识,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-03-03
  • javascript sort()对数组中的元素进行排序详解

    javascript sort()对数组中的元素进行排序详解

    在本篇文章里小编给大家整理是一篇关于javascript sort()对数组中的元素进行排序的相关知识点内容,需要的朋友们学习下。
    2019-10-10
  • JS设计模式之状态模式的用法使用方法

    JS设计模式之状态模式的用法使用方法

    JavaScript状态模式是一种行为型设计模式,核心是对象在其内部状态改变时改变其行为,状态模式将对象的行为封装到不同的状态类中,使得对象在不同状态下可以选择不同的行为,本文给大家详细的介绍一下状态设计模式在Js中的使用,需要的朋友可以参考下
    2023-08-08
  • 设为首页和收藏的Javascript代码(亲测兼容IE,Firefox,chrome等浏览器)

    设为首页和收藏的Javascript代码(亲测兼容IE,Firefox,chrome等浏览器)

    这篇文章主要介绍了设为首页和收藏的Javascript代码(亲测兼容IE,Firefox,chrome等浏览器)。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-11-11
  • 微信小程序-form表单提交代码实例

    微信小程序-form表单提交代码实例

    这篇文章主要介绍了微信小程序-form表单提交,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • jquery插件jquery.confirm弹出确认消息

    jquery插件jquery.confirm弹出确认消息

    这篇文章介绍了插件jquery.confirm弹出确认消息的实现方法,感兴趣的小伙伴们可以参考一下
    2015-12-12

最新评论