一、问题描述

问题是这样的,后台传了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. zabbix自定义key监控nginx和fpm(网站并发数)

    一. nginx编译参数 监控nginx,主要讲解监控并发数 --prefix=/usr/local/nginx --with-http_stub_status_module zabbix编译参数的查 ...

  2. LSP(分层服务提供程序)

    一.简介 LSP即分层服务提供商,Winsock 作为应用程序的 Windows 的网络套接字工具,可以由称为"分层服务提供商"的机制进行扩展.Winsock LSP 可用于非常广 ...

  3. vim调用替换文件内容

    :s/vivian/sky/ 替换当前行第一个 vivian 为 sky    :s/vivian/sky/g 替换当前行所有 vivian 为 sky    :n,$s/vivian/sky/ 替换 ...

  4. Hibernate环境搭建

    Hibernate的环境搭建,主要步骤分为一下四步: 首先创建一个工程,在工程里创建一个实体类User,在这个实体类中必须包含无参的构造器,和这个类对属性的存取方法(getter and setter ...

  5. MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error

    今天购物车突然不能添加了,发现redis报错了,重启了一下好了,一会又报错了. 错误信息: MISCONF Redis is configured to save RDB snapshots, but ...

  6. Alpha冲刺(十)

    Information:   队名:彳艮彳亍团队 组长博客:戳我进入 作业博客:班级博客本次作业的链接 Details: 组员1(组长)柯奇豪 过去两天完成了哪些任务 本人负责的模块(共享编辑)的前端 ...

  7. 安装并使用PICT,生成测试用例

    一.PICT简介 PICT工具是在微软公司内部使用的一款承兑组合的命令行生成工具,现在已经对外提供,可以在 http://download.microsoft.com/download/f/5/5/f ...

  8. .net EventHandler 事件处理

    通常定义事件 都是通过自定义委托的方式来实现, 今天使用EventHandler   委托来定义事件: public class NewMailEventArgs : EventArgs { priv ...

  9. c3p0-数据库连接池原理

    一直用c3p0很久了,但也没时间或没主动去研究过,直到最近频频在出现一些莫名其妙的问题,觉得还是有必要了解和研究一下. c3p0是什么 c3p0的出现,是为了大大提高应用程序和数据库之间访问效率的. ...

  10. 简单的jquery左侧导航栏和页面选中

    这里是要实现导航的左侧并选中的,此功能需引用jquery 左侧导航: <div class="box"> <ul class="menu"&g ...