一、问题描述

问题是这样的,后台传了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. CentOS Mysql安装配置

    一.mysql简介 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司.MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数 ...

  2. ubuntu14.04安装chromium以及flash插件

    之前找了好几个方法都不还用,今天突然发现,还挺简单的.命令如下: sudo apt-get updatesudo apt-get install chromium-browser#sudo add-a ...

  3. array_combine()

  4. BBS项目之后台管理

    一:后台管理,添加文章样式编写 创建 一个后台管理模板前段页面 <!DOCTYPE html> <html lang="en"> <head> ...

  5. sklearn中的随机森林

    阅读了Python的sklearn包中随机森林的代码实现,做了一些笔记. sklearn中的随机森林是基于RandomForestClassifier类实现的,它的原型是 class RandomFo ...

  6. es学习-索引配置

    1.创建一个新的索引并且添加一个配置 2.更新索引配置:(更新分词器为例子) 更新分词器前,一定要关闭索引,然后更新,最后再次开启索引 url:PUT http://127.0.0.1:9200/su ...

  7. C# 四舍五入的理解

    Math.Round(45.367,2)     //Returns   45.37 Math.Round(45.365,2)     //Returns   45.36 C#中的Round()不是我 ...

  8. element onclick 动态创建元素并绑定onclick事件

    <html> <head> <meta charset="UTF-8"> <title>b</title> <sc ...

  9. C#中使用多线程访问Winform中控件的若干问题

    我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题.然而我们并不能用传统方法来做这个问题,下面我将详细的介绍. 首先来看传统方法: public partial  ...

  10. Java多线程设计模式(二)

        目录(?)[-] Guarded Suspension Pattern Balking Pattern Producer-Consumer Pattern   Guarded Suspensi ...