antd pro 可编辑表格EditableProTable里有多选的select以及其反显问题

3,195 阅读2分钟

最近有一个需求是可编辑表格里需要自定义组件,比如可多选的select,遇到了很多问题,编辑的时候数据需要反显,valueEnum的类型,renderFormItem的写法等等,EditableProTable已经能满足了很多需求,但是文档有点点难看懂。

如果是单选下拉框的话可以写valueType:'select',我想要多选的select,chatGPT居然告诉我这样写:valueType:'select-multiple'……不知道他从哪儿学习到的,反正是错误的写法……

EditableProTable的示例代码如下:

  const [dataSource, setDataSource] = useState([{ id: '1', errorType: [2, 1] }]);
  const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
  const [isPE, setIsPE] = useState<boolean>(false); //控制是否能编辑
  
  const columns: ProColumns<any, any>[] = [
    {
      title: '序号',
      dataIndex: 'id',
      key: 'id',
      width: '15%',
      hideInTable: true,  //在列表内隐藏
    },
    {
      title: '异常类型',
      dataIndex: 'errorType',
      key: 'errorType',
      width: '15%',
      valueEnum: {        
      // 我发现如果要多选下拉正常的话,valueEnum和select的options都得写,有大佬可以解释一下吗
        1: '管理员',
        2: '编辑员',
        3: '操作员',
      },
      formItemProps: {
        rules: [{ required: true, message: '请输入异常类型' }],   
      },
      editable: isPE,     //这里可以控制isPE的值去操纵这个单元格是否可以编辑
      align: 'center',
      renderFormItem: () => {
        return (
          <Select
            mode={'multiple'}
            // onChange={() => onSelectChange(row)}
            // onClick={() => showSalespersonModal(row)}
            options={[{ label: '管理员', value: 1 },{ label: '编辑员', value: 2 },{ label: '操作员', value: 3 },            ]}
          />
        );
      },
    },
    {
      title: '描述',
      dataIndex: 'remark',
      key: 'remark',
      width: '15%',
      editable: isPE,
      align: 'center',
    },
    {
      title: '异常定位',
      dataIndex: 'errorLocation',
      key: 'errorLocation',
      width: '15%',
      valueType: 'select',
      mode: 'multiple', // 设置为多选
      formItemProps: {
        rules: [{ required: true, message: '请输入异常定位' }],
      },
      valueEnum: {
        1: { text: '类型1' },
        2: { text: '类型2' },
        3: { text: '类型3' },
      },
      editable: !isPE,
      align: 'center',
      renderFormItem: () => {
        return (
          <Select
            mode={'multiple'}
            options={[              { label: '类型1', value: 1 },              { label: '类型2', value: 2 },              { label: '类型3', value: 3 },            ]}
          />
        );
      },
    },
    {
      title: '原因描述',
      dataIndex: 'reason',
      key: 'reason',
      width: '15%',
      editable: !isPE,
      align: 'center',
    },
    {
      title: '操作',
      valueType: 'option',
      width: '15%',
      align: 'center',
      render: (text, record, _, action) => [
        <a
          key="editable"
          onClick={() => {
            action?.startEditable?.(record.id);
          }}
        >
          编辑
        </a>,
        <a
          key="delete"
          onClick={() => {
            setDataSource(dataSource.filter((item) => item.id !== record.id));
          }}
        >
          删除
        </a>,
      ],
    },
  ];
  
  
  return (<EditableProTable
        rowKey="id"
        value={dataSource}
        onChange={setDataSource}
        onlyAddOneLineAlertMessage="请保存后再新增!"
        columns={columns}
        recordCreatorProps={{
          position: 'bottom',
          record: () => ({
            id: (Math.random() * 1000000).toFixed(0),  //id作为rowKey必须唯一,新增的时候先随机取一个id
          }),
        }}
        editable={{
          type: 'multiple',
          editableKeys,
          onSave: async (rowKey, data, row) => {
            console.log(rowKey, data, row);
          },
          onChange: setEditableRowKeys,
        }}
      />
    );
  
  

image.png 这样写EditableProTable里面就可以有多选的select了。这只是一个简单的例子 后面还要写的更复杂一点、对一点接口,可编辑表格感觉还是挺常用的,但是其中的api都不是很熟。

antd pro的很多组件封装的都挺好的,使用起来比antd的舒服,但是也存在着过度封装的问题,我以前用proformlist嵌套proformlist的时候就出现了第二层的actionRef失效的问题,每次改第二层的数据,只能从第一层中解构出来,还是很麻烦的(不过也比写俩formlist嵌套要好点。)