react antd table表格点击一行选中数据的方法

一、前言

在这里插入图片描述

antd的table,默认是点击左边的单选/复选按钮,才能选中一行数据;

现在想实现点击右边的部分,也可以触发操作选中这行数据。

可以使用onRow实现,样例如下。

二、代码

1.表格样式部分

//表格table样式部分

{isRadio ?
                <Table
                dataSource={data.list}
                onRow={(record) => ({
                  onClick: () => {
                    this.selectRow(record);
                  },
                })}
                rowSelection={{
                  type: 'radio',
                  selectedRowKeys: selectedIdsInSearchTab,
                  onChange: this.onSelectChange,
                }} // 表格是否可复选,加type是单选,去掉是多选
                columns={this.getColumns()}
                rowKey={record => record.id}
                pagination={false}
                loading={loading}
                size="middle"
                bordered
                scroll={{ x: 1100 }}
              /> 
          :
              <Table
              dataSource={data.list}
              onRow={(record) => ({
                onClick: () => {
                  this.selectRow(record);
                },
              })}
              rowSelection={{
                selectedRowKeys: selectedIdsInSearchTab,
                onChange: this.onSelectChange,
                onSelect: this.onSelect,
                onSelectAll: this.onSelectAll,
              }} // 表格是否可复选,加type是单选,去掉是多选
              columns={this.getColumns()}
              rowKey={record => record.id}
              pagination={false}
              loading={loading}
              size="middle"
              bordered
              scroll={{ x: 1100 }}
            />
          }

说明:
(1)isRadio 是自己写的一个变量,用来区分是单选表格还是多选表格

(2)onRowthis.selectRow(record)方法是核心,用来实现点击一行数据即可选中(其实是点击 单选/多选按钮右边的部分时,触发这个方法)

(3)onChange: this.onSelectChange,这个方法是点击左边的单选/多选按钮时,会触发;

但是由于框架自身bug,翻页多选数据的话,id数组没有问题、内容数组会只保留当前页、无法保留前几页选中的内容;
所以多选时增加了onSelectonSelectAll方法,可以解决这个问题。

(4)加上 type: 'radio',表格就会展示为单选按钮;去掉,表格默认展示为多选按钮

(5)selectedRowKeys: selectedIdsInSearchTab,这个是保存选中行id的一个数组,必须加,数组有内容后,页面就会显示出哪行被选中的样式

2.onRowthis.selectRow(record)方法


  selectRow = (record) => {

    const {
      dispatch,
      TrainPlanManage_SelectBscUserT: { selectedIdsInSearchTab,selectedRowsInSearchTab },
      isRadio
    } = this.props;

    //如果是单选
    if(isRadio){
      //获取存放的key
      const selectedRowKeys = [record.id];
      //获取存放的数据value
      const selectedRows = [record];

      dispatch({
        type: 'TrainPlanManage_SelectBscUserT/updateSelectedIdsInSearchTab',
        selectedIds : selectedRowKeys,
        selectedRows: selectedRows,
      });
    }
    //否则是多选
    else{

      //获取存放的key
      const selectedRowKeys = [...selectedIdsInSearchTab];
      //获取存放的数据value
      const selectedRows = [...selectedRowsInSearchTab];  
      
      if (selectedRowKeys.indexOf(record.id) >= 0) {
        //当点击选中的数据,取消选中
        selectedRowKeys.splice(selectedRowKeys.indexOf(record.id), 1);
        //取消选中也要删除数组中的value
        selectedRows.forEach((element,index) => {
          if(element.id === record.id){
            //根据id获取到数组里当前数据的下标,并删除。
            selectedRows.splice(index,1)
          }
        });
      } else {
        selectedRowKeys.push(record.id);
        //将选中的数据加入数组里
        selectedRows.push(record)
      }
      
      //this.setState({ selectedRowKeys,selectedRows });    

      dispatch({
        type: 'TrainPlanManage_SelectBscUserT/updateSelectedIdsInSearchTab',
        selectedIds : selectedRowKeys,
        selectedRows: selectedRows,
      });
    }

  }

说明:

(1)TrainPlanManage_SelectBscUserT: { selectedIdsInSearchTab,selectedRowsInSearchTab }的意思是,从TrainPlanManage_SelectBscUserT.js里拿出2个变量来,selectedIdsInSearchTab是保存被选中id的数组,selectedRowsInSearchTab 是保存被选中整行数据的数组

(2)入参record,就是当前点击的行数据,单选时直接保存回那2个变量中即可;
多选时,先判断现有数组中是否存在当前点击行的id,如果存在,那就是取消选择的意思,从数组移除内容;
如果不存在,那就是新增,直接放入数组。

(3)selectedRows.splice(index,1)的意思是,从数组中删除下标为index的数据。

(4)dispatch方法,调用的是TrainPlanManage_SelectBscUserT.js里的方法,把处理好的数组保存进去用,如下:

export default {
  namespace: 'TrainPlanManage_SelectBscUserT',

  state: {
      selectedIdsInSearchTab:[],
      selectedRowsInSearchTab:[],

......

---------------------------------------
  reducers: {
  
    updateSelectedIdsInSearchTab(state, action) {
      return {
        ...state,
        selectedIdsInSearchTab: action.selectedIds || state.selectedIds,
        selectedRowsInSearchTab: action.selectedRows || state.selectedRows,
      };
    },
    
}    

(5)如果变量在同一个js中,也可以使用//this.setState({ selectedRowKeys,selectedRows }); 来保存。

3.onChange: this.onSelectChange方法

这个方法是点击左边的 单选/复选 按钮 触发的;

单选没有问题;

多选有问题,上方提到了,不过自己把onSelectonSelectAll方法加上,就可以解决问题,后续会有。

代码如下:

  // 复选框选中后的方法
  onSelectChange = (selectedIds, selectedRows) => {

    const {
      dispatch,
      TrainPlanManage_SelectBscUserT: { selectedIdsInSearchTab,selectedRowsInSearchTab },
      isRadio
    } = this.props;

    //如果是单选
    if(isRadio){
      //和原来保持一致
      dispatch({
        type: 'TrainPlanManage_SelectBscUserT/updateSelectedIdsInSearchTab',
        selectedIds,
        selectedRows,
      });
    }
    //否则是多选
    else{

      //这里管选中的行,都放到这个数组里
      if(selectedRowsInSearchTab !== null && selectedRowsInSearchTab !== '' && selectedRowsInSearchTab !== undefined) {
        for(let index in selectedRows){
          let flag = false;
          let id = selectedRows[index].id;
          for(let i in selectedRowsInSearchTab){
            if(selectedRowsInSearchTab[i].id === id){
              flag = true;
            }
          }
          if(!flag){
            selectedRowsInSearchTab.push(selectedRows[index]);
          }
        }
      }

      //然后放回去
      dispatch({
        type: 'TrainPlanManage_SelectBscUserT/updateSelectedIdsInSearchTab',
        selectedIds,
        selectedRows: selectedRowsInSearchTab,
      });

    }

  };

说明:
(1) 这个方法入参是选中行的id数组和选中行的数据数组。

(2)dispatch方法与上方相同,就是把数组直接保存进去。

(3)多选时,主要负责把多选的行保存进去,有去重。(解决框架翻页多选后只有当前行数据、没有之前页选中行数据的问题)

4.onSelect: this.onSelect方法

这个是点击列表左边部分的方框会触发的方法(点击右边的行部分不会触发)

代码如下:

  onSelect = (record,selected,selectedRows,nativeEvent) => {

    const {
      dispatch,
      TrainPlanManage_SelectBscUserT: { selectedIdsInSearchTab,selectedRowsInSearchTab },
      isRadio
    } = this.props;

    //如果取消选择,那就删掉数组元素
    if(selectedRowsInSearchTab !== null && selectedRowsInSearchTab !== '' && selectedRowsInSearchTab !== undefined){
      if(!selected){
        for(const index in selectedRowsInSearchTab){
          if(record.id === selectedRowsInSearchTab[index].id){
            selectedRowsInSearchTab.splice(index,1);
          }
        }
      }
    }

  }

说明:
这个负责取消选中行时,把行元素从数组中移除。(选中行时onChange负责装入元素了,这里不用管)

5.onSelect: this.onSelectAll方法

这个是点击列表左上方的全选方框会触发的方法

代码如下:

  onSelectAll = (selected,selectedRows,changeRows) => {

    const {
      dispatch,
      TrainPlanManage_SelectBscUserT: { selectedIdsInSearchTab,selectedRowsInSearchTab },
      isRadio
    } = this.props;
    
    //如果取消选择,那就删掉数组元素
    if(selectedRowsInSearchTab !== null && selectedRowsInSearchTab !== '' && selectedRowsInSearchTab !== undefined){
      if(!selected){
        for(const i in changeRows){
          let record = changeRows[i];
          for(const index in selectedRowsInSearchTab){
            if(record.id === selectedRowsInSearchTab[index].id){
              selectedRowsInSearchTab.splice(index,1);
            }
          }
        }
      }
    }

  }

说明:
这个负责取消选中行时,把行元素从数组中移除。(选中行时onChange负责装入元素了,这里不用管)

三、总结

1.这个方法可以实现点击表格行选中一行数据。

2.这个方法解决了翻页后、选中行数组丢失之前页的选中行、只保留当前页选中行的问题。(点击左边的选择框和右边的行都可以正常使用)

3.需要自己写onRow、onChange、onSelect、onSelectAll这4个方法

4.onRow实现点击行可以选中/取消选中本行;onChange负责点击左边按钮把选中数据放入数组;onSelect/onSelectAll负责点左边按钮取消选中时把数据从数组中移除。

5.打印日志发现,框架先执行onChange,后执行onSelect,不影响数据的放入/移除数组。(后续优化的话,应该可以把放入/移除操作写到一个方法里?比如都写onSelect里面)

四、备注

1.发现,rowKey={record => record.id}这个东西,是配置返回列表的哪个字段作为table中元素的id;如果列表返回有id的话,把id装入selectedRowKeys: selectedIdsInSearchTab中的selectedIdsInSearchTab数组,页面就会显示哪些行被选中;

但是如果数据列表没有叫id的字段,那么把其它值装入绑定数组selectedIdsInSearchTab没有效果,页面不知道选中的是哪行;

如果打印onChange里的selectedIds数组,会发现框架自己默认生成了一个数组当做了该行的id(比如0,1,2),后续用于实现选中行效果等。

所以,如果数据列表没有叫id的字段,那就修改rowKey={record => record.myid}这个东西,找到一个唯一值作为id才行。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以实现双击表格的某一行选中功能。可以通过在 `Table` 组件使用 `onRow` 属性,为每一行添加双击事件回调函数,来实现双击选中一行的功能。在回调函数,可以通过 `rowSelection` 组件提供的 `onChange` 方法,将选中的行记录下来。 以下是一个示例代码: ```jsx import React, { useState } from 'react'; import { Table } from 'antd'; const dataSource = [ { key: '1', name: 'John Doe', age: 32 }, { key: '2', name: 'Jane Smith', age: 28 }, { key: '3', name: 'Bob Johnson', age: 45 }, ]; const columns = [ { title: 'Name', dataIndex: 'name', key: 'name' }, { title: 'Age', dataIndex: 'age', key: 'age' }, ]; function TableWithDoubleClickSelection() { const [selectedRowKeys, setSelectedRowKeys] = useState([]); const handleRowDoubleClick = (record) => { setSelectedRowKeys([record.key]); }; const rowSelection = { selectedRowKeys, onChange: (selectedRowKeys, selectedRows) => { setSelectedRowKeys(selectedRowKeys); }, }; const rowProps = (record) => { return { onDoubleClick: () => handleRowDoubleClick(record), }; }; return ( <Table dataSource={dataSource} columns={columns} rowSelection={rowSelection} onRow={rowProps} /> ); } export default TableWithDoubleClickSelection; ``` 在上面的示例,我们首先定义了一个 `selectedRowKeys` 状态,用来记录选中的行。然后,在 `handleRowDoubleClick` 回调函数,我们根据双击的行数据,设置 `selectedRowKeys` 状态。最后,在 `rowProps` 回调函数,我们将双击事件绑定到每一行上。 这样,当用户双击某一行时,会触发 `handleRowDoubleClick` 回调函数,更新 `selectedRowKeys` 状态,并通过 `rowSelection` 组件提供的 `onChange` 方法,将选中的行记录下来。同时,由于我们使用了 `onRow` 属性,所以每一行都会绑定双击事件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐梦想永不停

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值