一、问题描述

问题是这样的,后台传了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. Maven01 环境准备、maven项目结构、编译/测试/打包/清除、安装、

    0 前提准备 0.1 安装java开发环境 0.2 安装maven工具 1 maven项目基本结构 如图所示,整个maven项目有业务文件.测试文件.POM依赖管理文件:其实还有一个资源文件resou ...

  2. 543. Diameter of Binary Tree 二叉树的最大直径

    [抄题]: Given a binary tree, you need to compute the length of the diameter of the tree. The diameter ...

  3. 如何启动jdeveloper中集成的weblogic

    1>运行jdeveloper,打开运行日志,入下图,日志最开始的红框部分就是打开weblogic的命令,将此命令复制出来执行即可打开weblogic 程序员的基础教程:菜鸟程序员

  4. Mysql中自定义函数编程

    1.语法 1.1 新建函数 Create function function_name(参数列表) returns 返回值类型 函数体 (1)函数名,应该合法的标识符,并且不应该与已有的关键字冲突. ...

  5. jQuary总结3: jQuery语法1

    1.jQuery样式操作 1.1 设置或者修改样式,操作的是style属性. 单样式语法: jQuery对象.css('属性名', '属性值') //html <div id="box ...

  6. Ubuntu下安装配置java及环境变量

    这里的办法不是在线安装,因为需要更新源(你懂的,费时费事~),so这里介绍在Ubuntu上手动下载安装配置Java环境变量 *系统:Ubuntu 16.4 1.下载jdk,直接用系统的Firefox浏 ...

  7. 关于linq to sql调用存储过程,出现"无法枚举查询结果多次"的问题

    DBML: [Function(Name="dbo.p_GetStudyStageSubjectGroup")] public ISingleResult<STUDYSTAG ...

  8. [Lua快速了解一下]Lua的model

    我们可以直接使用require(“model_name”)来载入别的lua文件,文件的后缀是.lua.载入的时候就直接执行那个文件了.比如: 我们有一个hello.lua的文件: print(&quo ...

  9. C和C++中的异常处理

    1.简介 许多的编程新手对异常处理视而不见,程序里很少考虑异常情况.一部分人甚至根本就不考虑,以为程序总是能以正确的途径运行.譬如我们有的程序设计者调用fopen打开一个文件后,立马就开始进行读写操作 ...

  10. 面试题: 已知一个含有n个不同元素的集合,要求打印其所有具有k个元素的子集(不允许有重复的)

    TX面试题2: 已知一个含有n个元素的集合,要求打印其所有具有k个元素的子集(不允许有重复的) 题目分析, 为了便于说明,不妨将问题简化一下: 已知一个盒子中有n个不同的球,分别标记为{a1,a2,. ...