antd table嵌套子表格 后端动态获取数据 rudex写法示例

3 篇文章 0 订阅

有一个需求是可以使主表格里每一栏数据展开,在子table里显示与其相关的子数据项,展开的时候去向后台请求数据。
另外如果请求的数据不存在则要不显示展开按钮。
用的组件库是Antd。

首先我们看Antd官方文档的Table有嵌套子表格的功能,
在这里插入图片描述
可见我们需要使用expandedRowRender参数,但是尝试在expandedRowRender函数中进行请求,会发现发出了连续的请求,所以我们把请求写在onExpand中,只在点击展开图表的时候发出一次。

            <Table
              expandIcon={expandIcon}
              onExpand={this.onExpand}
              expandedRowRender={record => expandedRowRender(record)}
              expandRowByClick="true"
              columns={columns}
              dataSource={records}
              rowKey={record => `${record.id}record`}
              style={{ backgroundColor: '#fff', marginTop: 16 }}
            />

之后我们写onExpand函数,注意这里的参数要写上expanded,代表是展开还是合并,我之前没写这个参数,只写了record,就一直无法接受到真正的record,record总是显示true或者false,后来又去看官方文档才发现这个问题。

  onExpand = (expanded, record) => {
    const { actions } = this.props;
    const rid = record.id;
    actions.fetchProcess(rid);
  }

我们在action中请求数据,在reducer中改变状态。

function receiveProcess(processRecords) {
  return {
    type: at.PROCESS,
    processRecords,
    receivedAt: Date.now(),
  };
}

export const fetchProcess = id => async (dispatch) => {
  axios.get(`YOUR URL`).then((resp) => {
    dispatch(receiveProcess(resp.data));
  })
    .catch(({ response }) => dispatch(Notification(response)));
};
export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case at.RECEIVE_RECORD:
      return Object.assign({}, state, { records: action.data });
    case at.PROCESS: {
      return Object.assign({}, state, {
        process: {
          ...state.process,
          [action.processRecords[0].id]: action.processRecords,
        },
      });
    }
    ....

这里需要注意的一个点就是,我们用了id来作为key,对应的value为我们要展开的数据,这样存数据,用父数据项的id去选择需要的数据,就不会出现展开的子table数据一样的问题。ANTD里也有一个参数expandedRowKeys有相同功能。
在收回展开的时候,也就是expanded===false的时候,可以将对应id的数据清空,防止数据冗余。
最后我们写expandedRowRender函数,拿到数据,渲染子表。

    const expandedRowRender = (rrecord) => {
      let { process } = this.props;
      const { id } = rrecord;
      if (process) {
        if (process[id]) {
          process = process[id];
          const columns = [];
          if (process[0].service_name !== null) {
            columns.push(
              {
                .......
              }
          );
          return (
            <Table
              columns={columns}
              dataSource={process}
              rowKey={record => `${record.id}record`}
              pagination={false}
            />
          );
        }
      }
      return null;
    };

在这里睬的坑是每次点击请求的时候,发现调用了两次expandedRowRender,第一次的时候还没有拿到新数据,第二次才有,所以加了if判断对应的数据是否拿到。

然后要实现数据不存在的时候点击图标不显示

    const expandIcon = (props) => {
      if (props.record.record_eid) {
        if (props.expanded) {
          return ( // eslint-disable-next-line
            <a
              style={{ color: 'black' }}
              onClick={(e) => {
                props.onExpand(props.record, e);
              }}
            >
              <Icon type="minus" className="minus-square" />
            </a>
          );
        }
        return ( // eslint-disable-next-line
          <a
            style={{ color: 'black' }}
            onClick={(e) => {
              props.onExpand(props.record, e);
            }}
          >
            <Icon type="plus" className="plus-square" />
          </a>
        );
      }
      return (<a onClick={(e) => e.preventDefault()} />); // eslint-disable-line
    };

效果如图
在这里插入图片描述

今天的分享就到这里了,小菜刚刚学习前端,如果有发现我代码有问题的或者有更优雅写法的,希望不吝赐教,万分感谢。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值