ant design 中表格怎么合并单元格

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ant design 中表格怎么合并单元格相关的知识,希望对你有一定的参考价值。

参考技术A 在WPS软件内,首先选中你要合并的那几个单元格

然后点击“合并居中”按钮如下图所示

就可以把这3个单元格变为一个单元格了。如下图所示:

单击表格单元格内的按钮时无法更新状态,React Ant Design

【中文标题】单击表格单元格内的按钮时无法更新状态,React Ant Design【英文标题】:Unable to update the state when button inside table cell clicked , React Ant Design 【发布时间】:2019-03-16 23:51:55 【问题描述】:

我想在点击表格单元格时更新状态。但是事件handleClick 没有触发。如果我在类外声明handleClick,则事件调用发生但状态未定义消息即将到来。

如果我们单击类外的其他单元格,如何更新状态。 下面是我的代码

import React from 'react';
import  connect  from 'react-redux';
import  bindActionCreators  from 'redux';
import  Table, Icon, Switch, Radio, Form, Divider, Button, Modal  from 'antd';

import * as productActions from './../../redux/actions/productActions';

const handleClick = (product) => 
  debugger;
  
  //UNABLE TO UPDATE STATE HERE
  // this.setState(
  //   visibleDeletePopup: true
  // );
  alert(JSON.stringify(product));


const columns = [
  title: 'Name',
  dataIndex: 'name',
  key: 'name',
  width: 150,
  render: text => <a href="javascript:;">text</a>,
, 
  title: 'Full',
  dataIndex: "stockIn['full']",
  key: `stockIn['full'`,
  width: 70,
,

  title: 'Half',
  dataIndex: "stockIn['half']",
  key: `stockIn['half'`,
  width: 70,
,

  title: 'Quarter',
  dataIndex: "stockIn['quarter']",
  key: `stockIn['quarter'`,
  width: 70,
,

  title: '90',
  dataIndex: "stockIn['ninty']",
  key: `stockIn['ninty']`,
  width: 70,
, 
  title: 'Category',
  dataIndex: 'category',
  key: 'category',
, 
  title: 'Action',
  key: 'action',
  width: 360,
  render: (text, record) => (<span>
    <button href="javascript:;" onClick=() => handleClick(record)>Edit-record.name</button>
    /* <Divider type="vertical" />
    <a href="javascript:;">Delete</a>
    <Divider type="vertical" />
    <a href="javascript:;" className="ant-dropdown-link">
      More actions <Icon type="down" />
    </a> */
  </span>
  ),
];


const showHeader = true;
let footer = () => 0;
const scroll =  y: 300 ;
const pagination =  position: 'bottom' ;


class ProductsPage extends React.Component 
  constructor(props) 
    super(props);
    this.onProductSave = this.onProductSave.bind(this);
    this.onChange = this.onChange.bind(this);

    this.state = 
      bordered: true,
      loading: false,
      pagination,
      size: 'small',
      expandedRowRender,
      title: title,
      showHeader,
      footer,
      rowSelection: ,
      hasData: true,
    ;

    //Popup and submit button
    this.state.buttonSubmitLoader = false;
    this.state.visibleDeletePopup = false;
  


  handleClick = (product) => 
    //UPDATE STATE // how?
  

  showModal = () => 
    this.setState(
      visibleDeletePopup: true,
    );
  

  handleOk = () => 
    this.setState( buttonSubmitLoader: true );
    setTimeout(() => 
      this.setState( buttonSubmitLoader: false, visibleDeletePopup: false );
    , 3000);
  

  handleCancel = () => 
    this.setState( visibleDeletePopup: false );
  


  render() 
    const state = this.state;
    return (
      <div>
        <div>
          <Table ...this.state
            columns=columns
            dataSource=state.hasData ? this.props.products : null
            footer=() => this.getFooterDetails(this.props.products)
            pagination= pageSize: 5 
          />
        </div>
       
      </div>
    );
  

  componentDidMount() 
    const props = this.props;
    props.actions.loadProducts();
  

  courseRow(item, index) 
    return <li key=index>item.name</li>;
  

  onProductSave(product) 

    this.props.actions.createProduct(product);
    this.setState(
      product: ""
    );
  

  onChange(e) 
    this.setState(
      product: e.target.value
    );
  

  getFooterDetails(products) 
    return <label class="text-success">Total Records Count is products.length</label>;
  




function mapStateToProps(state, ownProps) 
  //In state.products, product is coming from root reducer, if you change 
  //the name products to abhi_products , then here you need to call products:state.abhi_products 
  return 
    products: state.products
  


function mapDispatchToProps(dispatch) 
  return 
    actions: bindActionCreators(productActions, dispatch)
  


export default connect(mapStateToProps, mapDispatchToProps)(ProductsPage);

   

【问题讨论】:

【参考方案1】:

setState 仅在组件内有效。如果你想在声明的函数中执行 setState 并且想要执行 setState 则必须将此上下文传递给函数。

下面将在组件内工作

  handleClick = product => 
      this.setState(
         visibleDeletePopup: true
     );
  

更新:

整个组件代码可以修正如下

import React from 'react';
import  connect  from 'react-redux';
import  bindActionCreators  from 'redux';
import  Table, Icon, Switch, Radio, Form, Divider, Button, Modal  from 'antd';

import * as productActions from './../../redux/actions/productActions';


let footer = () => 0;


class ProductsPage extends React.Component 
  constructor(props) 
    super(props);
    this.state = 
      bordered: true,
      loading: false,
      pagination:  position: 'bottom' ,
      size: 'small',
      expandedRowRender,
      title: title,
      showHeader: true,
      footer,
      rowSelection: ,
      hasData: true,
    ;

     handleClick = product => 
        this.setState(
           visibleDeletePopup: true
       );
    
    //Popup and submit button
    this.state.buttonSubmitLoader = false; // never mutate state like this instead use setState method
    this.state.visibleDeletePopup = false;
  

  showModal = () => 
    this.setState(
      visibleDeletePopup: true,
    );
  

  handleOk = () => 
    this.setState( buttonSubmitLoader: true );
    setTimeout(() => 
      this.setState( buttonSubmitLoader: false, visibleDeletePopup: false );
    , 3000);
  

  handleCancel = () => 
    this.setState( visibleDeletePopup: false );
  

  componentDidMount() 
    const props = this.props;
    props.actions.loadProducts();
  

  courseRow = (item, index) => 
    return <li key=index>item.name</li>;
  

  onProductSave = product => 
    this.props.actions.createProduct(product);
    this.setState(
      product: ""
    );
  

  onChange = e => 
    this.setState(
      product: e.target.value
    );
  

  getFooterDetails = products => 
    return <label class="text-success">Total Records Count is products.length</label>;
  


  render() 
    const  hasData  = this.state;
    const  products  = this.props;
    const columns = [
      title: 'Name',
      dataIndex: 'name',
      key: 'name',
      width: 150,
      render: text => <a href="javascript:;">text</a>,
    , 
      title: 'Full',
      dataIndex: "stockIn['full']",
      key: `stockIn['full'`,
      width: 70,
    ,
    
      title: 'Half',
      dataIndex: "stockIn['half']",
      key: `stockIn['half'`,
      width: 70,
    ,
    
      title: 'Quarter',
      dataIndex: "stockIn['quarter']",
      key: `stockIn['quarter'`,
      width: 70,
    ,
    
      title: '90',
      dataIndex: "stockIn['ninty']",
      key: `stockIn['ninty']`,
      width: 70,
    , 
      title: 'Category',
      dataIndex: 'category',
      key: 'category',
    , 
      title: 'Action',
      key: 'action',
      width: 360,
      render: (text, record) => (<span>
        <button href="javascript:;" onClick=() => this.handleClick(record)>Edit-record.name</button>
      </span>
      ),
    ];
    return (
      <div>
        <div>
          <Table ...this.state
            columns=columns
            dataSource=hasData ? products : null
            footer=() => this.getFooterDetails(products)
            pagination= pageSize: 5 
          />
        </div>
      </div>
    );
  



const mapStateToProps = (state, ownProps) => 
  //In state.products, product is coming from root reducer, if you change 
  //the name products to abhi_products , then here you need to call products:state.abhi_products 
  return 
    products: state.products
  


const mapDispatchToProps = dispatch => 
  return 
    actions: bindActionCreators(productActions, dispatch)
  


export default connect(mapStateToProps, mapDispatchToProps)(ProductsPage);

【讨论】:

你能给我举个例子吗?如果我将 handleclick() 放在类中,则列渲染在类之外。它无法找到该方法。 (能不能同时显示html和js) 所以,你要求我在类本身中声明列,以便可以访问 handleClick 方法。 @Abhi 是的,这就是您需要在 react 中实现的方式,确保您将所有内容保存在组件中。我在回答中做了一些小的更正。现在可以了 检查并告诉我 我正在检查。antd 组件很大 (html, events) 。制作我的自定义组件并将antd组件放在里面还是保持原样(文件可能会越来越大)的最佳实践是什么【参考方案2】:

您可以像这样在类构造函数中声明列变量:

this.columns = []

事件将是(当然你需要绑定handleClick):

onClick=() => this.handleClick(record)

或者你可以像你一样在外面声明列并使用类上下文调用事件处理程序:

onClick=() => ProductsPage.prototype.handleClick(record)

【讨论】:

未捕获类型错误:ProductsPage.prototype.handleClick 不是函数【参考方案3】:
    enter code here

const getColumns = (handleClick) =>  // Note here
  return [
   
      title: 'Name',
  dataIndex: 'name',
  key: 'name',
  width: 150,
  render: text => <a href="javascript:;">text</a>,
, 
  title: 'Full',
  dataIndex: "stockIn['full']",
  key: `stockIn['full'`,
  width: 70,
,

  title: 'Half',
  dataIndex: "stockIn['half']",
  key: `stockIn['half'`,
  width: 70,
,

  title: 'Quarter',
  dataIndex: "stockIn['quarter']",
  key: `stockIn['quarter'`,
  width: 70,
,

  title: '90',
  dataIndex: "stockIn['ninty']",
  key: `stockIn['ninty']`,
  width: 70,
, 
  title: 'Category',
  dataIndex: 'category',
  key: 'category',
, 
  title: 'Action',
  key: 'action',
  width: 360,
  render: (text, record) => (<span>
    <button href="javascript:;" onClick=() => handleClick(record)>Edit-record.name</button>
    /* <Divider type="vertical" />
    <a href="javascript:;">Delete</a>
    <Divider type="vertical" />
    <a href="javascript:;" className="ant-dropdown-link">
      More actions <Icon type="down" />
    </a> */
  </span>
  ),
]

然后在你的组件里面

 <Table ...this.state
    columns=getColumns(this.handleClick) // and Here
    dataSource=state.hasData ? this.props.products : null
    footer=() => this.getFooterDetails(this.props.products)
    pagination= pageSize: 5 
   />

【讨论】:

【参考方案4】:

你可以使用列标签

<Table pagination=false dataSource=this.state.responsible>
    <Column title="name" dataIndex="name" key="name" />
    <Column title="Category" dataIndex="email" key="Category" />

  <Column title="Actions" dataIndex="Actions" key="Actions"
 render=(text, element, index)=>
   return (<div>
    <i className="fas fa-edit text-success m-1" style= cursor: "pointer" 
      onClick=() => this.handleClick()
    ></i>
    <i className="fas fa-trash text-danger m-1" style= cursor: "pointer" 
      onClick=() => this.Delete(element._id)
 
      
    ></i>

  </div>)
 
  />
      
      </Table>   

【讨论】:

以上是关于ant design 中表格怎么合并单元格的主要内容,如果未能解决你的问题,请参考以下文章

ant design vue多样化表格,合并单元格,数据必须以行遍历

react ,ant Design UI中table组件合并单元格并展开详情的问题

Ant Design中Table动态获取数据合并单元格问题

实操记录之-----Ant Design of Vue 增强版动态合并单元格,自动根据数据进行合并,可自定义横纵向合并

在HTML表格中怎么合并单元格?

Markdown表格中换行、合并单元格