一、问题描述

问题是这样的,后台传了xArr = [x1, x2,...,xn]和yArr = [y1, y2, ..yn]两个数组,前端要渲染出表格并且可以填写每个单元格的值,然后按照一定数据结构保存并传给后台,并且再次获取这个数据结构和数组xArr、yArr可以自己渲染出这个表?实现新增和修改的功能。大致界面效果如下图所示:

y1, y2,...,yn作为列名,x1,x2, ..., xn作为第一列数据,此业务模型是一种常见的表格,只不过要求行列都不固定,由后台数据提供并且动态生成。还要能够实现修改功能。本质上是一个动态渲染可编辑Table的问题。难点在于动态构建表格并且实现数据展示和保存。

二、解决思路

(1)数据转换成表格后,处理起来就简单了,如果以常见的Table组件为例,只需要构建columns和dataSource两个数组数据即可渲染出表格;

(2)渲染出表格后,表格每一个余下的单元格都要可输入,可以考虑单元格利用render渲染出Input组件,通过Input的操作onChange或onBlur去改变数据并存储。

(3)数组是引用类型,可以利用引用类型只要没有深拷贝或改变指针指向内存地址就不变的原理,方便记录操作后的数据。

三、解决方法(以React结合ant design UI的Table组件为例):

(1)动态构建columns(表格列数据)和dataSource(表格数据源)渲染出表格。(Table可参考 https://ant.design/components/table-cn/#header)

 const xArr = ['x1', 'x2', 'x3', 'x4'];
const dataSource = xArr.map((v, i) => ({
key: String(i),//此处自定义表格每一行的唯一key,如果没有设置唯一标志会报错
y0: v,//第一列数据即显示X1-Xn的那一列
})); const yArr = ['y1', 'y2', 'y3', 'y4', 'Y5'];
const columns = [{
title: ' ',
dataIndex: 'y0',//第一列y0为列的dataIndex,用于显示x1-xn
}, ...yArr.map(item => ({//其他列通过yArr循环得到,并用...解构直接合并为columns
title: item,
dataIndex: item,
}))];

这样就得到形如dataSource = [{ key: '0', y0:'x1'}, { key: '0', y0:'x1'},...];  columns = [{ title: '', dataIndex: 'y0'},{ title: 'y1', dataIndex: 'y1'},...];的表格数据,将此数据源传入表格组件Table,即可渲染出表格如下:

<Table columns={columns} dataSource={dataSource} />

(2)表格添加Input并且根据onChange/onBlur事件动态记录dataSource的变化。

 const columns = [{
title: ' ',
dataIndex: 'y0',
}, ...yArr.map(item => ({
title: item,
dataIndex: item,
render: (text, record) => (
<Input defaultValue={record[item]} onChange={(e) => { record[item] = e.target.value; }} />
),
}))];

渲染效果如下:

四、完整代码

/**
* @author xiao-pengyou
* @create date 2019-03-27
* @desc 动态可编辑表格
* */ import React, { PureComponent } from 'react';
import { Table, Input } from 'antd'; export default class Demo extends PureComponent {
state = { dataSource: [] }; componentDidMount() {
const xArr = ['x1', 'x2', 'x3', 'x4'];
const dataSource = xArr.map((v, i) => ({key: String(i),y0: v}));
this.setState({ dataSource });//dataSource不能在render里面构建,在render里面构建每次重新渲染的时候dataSource会被重新构建,指针指向变化导致先前的修改不能被跟踪
} render() {
const yArr = ['y1', 'y2', 'y3', 'y4', 'y5'];
const that = this;//定义中间量that=this确保columns内部onChange事件作用域为当前组件,方便调用forceUpdate()强制渲染表格
const columns = [{
title: ' ',
dataIndex: 'y0',
}, ...yArr.map(item => ({
title: item,
dataIndex: item,
render: (text, record) => (
<Input value={record[item]} onChange={(e) => { record[item] = e.target.value; that.forceUpdate(); }} />
),
}))];//最终的dataSource就是我们想要的数据结构,修改时直接把这个dataSource传给构建的表格就可以渲染
return <Table columns={columns} dataSource={this.state.dataSource} bordered pagination={false} />;//bordered设置边框,pagination=false取消分页功能,可以不用在意此参数
}
}

  最终效果(控制台输出为提交给后台的dataSource数组):

以上就是一个动态列的可编辑表格的React实现方式。如有问题欢迎留言批评指正,谢谢!

本文为原创博客,非法抄袭或复制将追究法律责任,转载请注明出处:https://www.cnblogs.com/xiao-pengyou/

动态渲染可编辑单元格的Table的更多相关文章

  1. FineUI大版本升级,外置ExtJS库、去AXD化、表格合计行、表格可编辑单元格的增删改、顶部菜单框架

    这是一篇很长的文章,在开始正文之前,请允许我代表目前排名前 20 中唯一的 .Net 开源软件 FineUI 拉下选票: 投票地址: https://code.csdn.net/2013OSSurve ...

  2. 扩展jquery easyui datagrid编辑单元格

    扩展jquery easyui datagrid编辑单元格 1.随便聊聊 这段时间由于工作上的业务需求,对jquery easyui比较感兴趣,根据比较浅薄的js知识,对jquery easyui中的 ...

  3. js如何实现动态点击改变单元格颜色?

    js如何实现动态点击改变单元格颜色? 一.总结 1.通过table的rows属性,遍历表格所有行,然后通过cells属性,遍历每一行中的单元格. 2.遍历的过程中,动态的为每一个单元格定义单击事件,改 ...

  4. 获取wpf datagrid当前被编辑单元格的内容

    原文 获取wpf datagrid当前被编辑单元格的内容 确认修改单元个的值, 使用到datagrid的两个事件 开始编辑事件 BeginningEdit="dataGrid_Beginni ...

  5. listview 样式 LVS_REPORT 与 LVS_EDITLABELS 编辑单元格时,当前行第一列内容不显示

    今天想做一个可编辑单元格的 listview,样式是 LVS_REPORT 与 LVS_EDITLABELS 网上搜索了一些相关资料,照葫芦画瓢写了一个,可测试的时候发现,当从第2列开始编辑的时候,第 ...

  6. LVC函数重要参数 EDT_CLL_CB:退出可编辑单元格时回调

    6. I_GRID_SETTINGS 参数属性该参数用于设置Grid相关参数(打印.单元格回调):类型为:LVC_S_GLAY,该结构包括:01) COLL_TOP_P:最小化 TOP_OF_PAGE ...

  7. Swift - 可编辑表格样例(可直接编辑单元格中内容、移动删除单元格)

    (本文代码已升级至Swift3)   本文演示如何制作一个可以编辑单元格内容的表格(UITableView). 1,效果图 (1)默认状态下,表格不可编辑,当点击单元格的时候会弹出提示框显示选中的内容 ...

  8. ABAP 动态内表添加单元格颜色字段

    *动态内表alv显示时要求某些单元格显示颜色 *wa_fldcat-datatype不能添加LVC_T_SCOL类型,在创建好内表之后,再添加颜色列. DATA: wa_fldcat TYPE lvc ...

  9. EasyUI DataGrid 编辑单元格

    如下图: 现改为单击某个单元格只对此单元格进行可编辑 <TABLE>标记添加 onClickCell <table id="dg" class="eas ...

随机推荐

  1. C++细节理解

    1.为什么static类外初始化不需要static关键字 答:因为类外static变量或函数表示限定在此源文件中才能使用,而类中的static变量或函数表示由本类及其所有对象共享,如果在类外初始化或定 ...

  2. 洛谷 P3659 [USACO17FEB]Why Did the Cow Cross the Road I G

    //神题目(题目一开始就理解错了)... 题目描述 Why did the cow cross the road? Well, one reason is that Farmer John's far ...

  3. pcl知识

    1.pcl/io/pcd_io.h pcl/io/ply_io.h pcl::PLYReader reader; pcl::PCDWriter pcdwriter; 读取ply pcd 2.voidl ...

  4. mysql中查看表结构的sql语句

    mysql查看表结构命令,如下: desc 表名;show columns from 表名;describe 表名;show create table 表名; use information_sche ...

  5. SpringMVC 细节学习

    使用Spring MVC,配置DispatcherServlet是第一步  DispatcherServlet是前置控制器,配置在web.xml文件中的 .拦截匹配的请求,Servlet拦截匹配规则要 ...

  6. 【转载】rabbitmq的发布确认和事务

    地址:https://my.oschina.net/lzhaoqiang/blog/670749 摘要: 介绍confirm的工作机制.使用spring-amqp介绍事务以及发布确认的使用方式.因为事 ...

  7. Codeigniter框架前后台部署(多目录部署)

    个网站一般包含前台和后台并且访问的url是不同的,Codeigniter怎么来部署呢? 在网上看到了一篇比较好的文章: 在下载好的ci的根目录建立一个目录 admin 将application目录中的 ...

  8. javascrip总结42:属性操作案例: 点击盒子,改变盒子的位置和背景颜色

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  9. 第01章 ElasticSearch简介

    本章内容 Apache Lucene是什么. Lucene的整体架构. 文本分析过程是如何实现的. Apache Lucene的查询语言及其使用方法. ElasticSearch的基本概念. ELas ...

  10. 一、Numpy基础--数组

    (一)Numpy数组对象 Numpy中的nadrray是一个多维数组对象,该对象由两部分组成: 实际的数据 描述这些数据的元数据 大部分的数组操作仅仅修改元数据部分,而不改变底层的实际数据. 数组的数 ...