类别:企业动态 发布时间:2021-01-05 浏览人次:
最近因为业务接触了antd,使用antd完成一个复杂的树形表格的显示以及修改。在这其中遇见了不少坑,很多功能antd只写了初步的功能,更为细化的功能只能自己完善。踩过的坑都写在了这里。
树形表格的显示
在antd中对于表格的key值有着严格的控制,每一个row都必须有一个独一无二的key值,可以是数字也可以是字符串。这一点和我曾经使用过得iview有着很大的区别。react使用key来代表每一行是为了避免重新渲染的问题,这个优化也在实际的开发中带来了不少的问题。比如新建行时需要自定义新key。
下面直接上一下代码及代码效果,这是一个三级的树形表格,且其中包含二级标题。
最终效果
colums标题: 简易版标题,随着功能的增加,我们将增加colums的复杂度。
let columns = [ title: '题目', dataIndex: 'text' title: '类型', children: [ title: '一级', dataIndex: 'text1' title: '二级', dataIndex: 'text2', title: '内容', dataIndex: 'content' title: '答案', dataIndex: 'answer', title: '类型', dataIndex: 'mark_type', className: 'line' title: '版本', dataIndex: 'version', className: 'line' title: '一级内容点', dataIndex: 'value1', className: 'line' title: '二级内容点', dataIndex: 'value2', className: 'line' title: '操作', key: 'action', width: 205
data数据:
let data = [{ "key": 1, "text": "题目一", "children": [{ "key": 11, "text1": "数学一", "children":[] }, { "key": 12, "text1": "语文一", "value1": "语文", "children": [{ "key": 121, "value2": "选择", "text2": "选择题", "content": "题目内容", "answer": "A", "mark_type": "1", "version": "1" "key": 122, "value2":"填空", "text2": "填空题", "content": "题目内容", "answer": "梅花", "mark_type": "1", "version": "1" "key": 123, "value2": "阅读", "text2": "阅读题", "content": "题目内容", "answer": "野蛮生长", "mark_type": "1", "version": "1" "key": 124, "value2": "文言文", "text2": "文言文", "content": "题目内容", "answer": "滕王阁序", "mark_type": "1", "version": "1" }, { "key": 2, "text": "题目二", "children": [ { "key": 21, "text1": "英语一", "value1": "英语", "children": [{ "key": 211, "value2": "完型", "text2": "完形填空", "content": "题目内容", "answer": "ABC", "mark_type": "2", "version": "1" "key": 212, "value2": "一级代码", "text2": "选择", "content": "题目内容", "answer": "D", "mark_type": "2", "version": "1" }];
增加子项数据
增加子项数据使用操作中的增加按钮进行增加,增加按钮设置为图形,更为形象具体清晰化。
//button样式使用antd自带icon样式 Button type="primary" shape="circle" icon="plus" size={'small'} this.handleAdd.bind(this, record)} /
注意事项:
1、对于最子项来说没有增加子项选择,需要对不同数据行进行不同处理
2、不同数据行新增数据的内容不同,字段也不同
3、新增之后需要点击确认或者取消
4、加入数据点击确认之后需要添加于当前key下的children中
本想使用antd自带的editable属性,但是这个属性不支持二级标题的编辑,所以只有自己写render
这个问题,在7102年就提出来了,但是已经8102年了快9102年都没有更新。
新增一级类型题目样式
新增二级类型题目样式
这里就部分render代码:
//分级标题 title: '类型', children: title: '一级', dataIndex: 'text1', render: (text, record) = { if (this.state.isEditing this.state.editingOneKey === record.key) return Input defaultValue={text} onChange={(e) = { this.changeEdit(e, record.key, 'text1') }} / return text title: '二级', dataIndex: 'text2', render: (text, record) = { if (this.state.isEditing this.state.editingTwoKey === record.key) return Input defaultValue={text} onChange={(e) = { this.changeEdit(e, record.key, 'text2') }} / return text //select选择 title: '内容', dataIndex:'content', render:(text, record) = { if (text === 0) text = '内容一'; if (text === 1) text = '内容二'; if (this.state.isEditing this.state.editingTwoKey === record.key) { return Select defaultValue={text} onChange={(e) = { this.changeEdit(e, record.key, 'flag') }} getPopupContainer={triggerNode = triggerNode.parentNode} Option value='0' 有效 /Option Option value='1' 无效 /Option /Select return text
注意展开
如果对一行未展开的行下新增数据,那么无法看到打开的编辑状态是一个非常糟糕的问题。所以我们需要在新增子项的时候自动展开父项。
//steate初始化 expandedRows: [] //展开行 //render 初始化 Table bordered expandedRowKeys={this.state.expandedRows} onExpandedRowsChange={this.changeExpandedRows.bind(this)} //自动展开变化,获取当前展开行 changeExpandedRows = (expandedRows) = { this.setState({ expandedRows //增加函数中 let rows = this.state.expandedRows; rows.push(record.key); this.setState({ expandedRows: rows
删除行数据
删除在antd中相较比较简单,因为antd的table每行都有key属性,key是唯一且必须的属性,所以只要过滤掉包含目的key的数据即可视为删除。因为这是树形数据,普通的遍历无法进行操作,所以使用深度优先遍历来进行数据处理,也可以使用广度优先,根据数据来变更。
handleDelete = (key) = { let data = this.state.data; data = dsFilter(data, key); this.setState({ data function dsFilter(dealData, dealKey) { for (let i = 0; i dealData.length; i++) { if (dealData[i].children dealData[i].children.length 0) { dealData[i].children = dsFilter(dealData[i].children, dealKey); return dealData.filter(item = item.key !== dealKey);
修改某些字段
修改和新增的colums相同,不过修改需要保存之前的值。需要在input或select中设置defaultValue={text}来保证初始值相同
保存
无论是新增修改还是删除,都需要进行保存。这里使用 和 来代表确定和取消。
同时需要注意,如果在一行的编辑中点击其他行的操作,需要将之前行的操作视为取消。
div Button shape="circle" icon="check" size={'small'} '#65BF34', color: '#FFF', border: 'none' }} this.saveEdit.bind(this, record.key)} Button shape="circle" icon="close" size={'small'} '#FF3333', color: '#FFF', border: 'none' }} this.cancelEdit.bind(this, record.key)} /div
修改顺序
修改顺序就是修改数据在数组中的顺序,使用简单的temp进行交换即可。
shiftUp = (key) = { let data = this.state.data; data = dsShift(data, key); this.setState({ data function dsShift(dealData, dealKey) { for (let i = 0; i dealData.length; i++) { if (dealData[i].children dealData[i].children.length 0) { dealData[i].children = dsShift(dealData[i].children, dealKey); if (dealData[i].key === dealKey) { if (i === 0) { message.warning('该行已置顶!'); break; let temp = dealData[i - 1]; dealData[i - 1] = dealData[i]; dealData[i] = temp; break; return dealData; shiftDown = (key) = { let data = this.state.data; data = dsShift(data, key); this.setState({ data function dsShift(dealData, dealKey) { for (let i = 0; i dealData.length; i++) { if (dealData[i].children dealData[i].children.length 0) { dealData[i].children = dsShift(dealData[i].children, dealKey); if (dealData[i].key === dealKey) { if (i === dealData.length - 1) { message.warning('该行已置尾!'); break; let temp = dealData[i + 1]; dealData[i + 1] = dealData[i]; dealData[i] = temp; break; return dealData;
总结
在进行表格数据操作中,需要进行变量的保存,这里就没有多写了。总的来说antd是个好组件,大部分功能都很齐全,但是很多细节还是需要自己进行完善。
补充知识:Antd(Ant-design),嵌套子表格(expandedRowRender)的异步获取数据
使用阿里的ant-design开源框架,要在表格里面嵌套子表格,需要在用户点击父表格的一行数据后,获取该行的key,然后去异步请求后台的数据用来填充子表格的内容。
如果这样写(省略无关代码):
expandedRowRender = (record) = { dispatch({ type: 'flow/getPlanList', payload: { contractId: record.contract_id, // 该参数是从父表格带过来的key callback: () = { const { flow: { data }, } = this.pro凡科抠图; this.setState({ secData: data.list, console.log("返回数据(PlanList):" + JSON.stringify(this.state.secData)); return ( Table columns={secColumns} dataSource={this.state.secData} pagination={false} render() { return( Card {this.renderForm()} div Table expandedRowRender={this.expandedRowRender} loading={loading} rowSelection={rowSelection} dataSource={list} columns={columns} pagination={paginationPro凡科抠图} scroll={{ x: 2500}} size = 'middle' expandRowByClick={true} onSelect={this.seFn} /div /Card }
则会出现不断的发起请求的现象:
这是因为,expandedRowRender 实际上是在 Table 组件的 render 方法中调用的,React render 中用 dispatch 会造成重复调用的问题,dispatch - setState - render - dispatch - setState - render,循环往复。所以应该把 dispatch 放在 onExpand 中。
onExpand = (expanded, record) = { const { dispatch } = this.pro凡科抠图; dispatch({ type: 'flow/getPlanList', payload: { contractId: record.contract_id, callback: () = { const { flow: { data }, } = this.pro凡科抠图; this.setState({ secData: data.list , console.log("返回数据(PlanList):" + JSON.stringify(this.state.secData)); }
但是单纯的这样做,又会带来新的问题,就是子表格的所有数据都变成了相同的。
本人的解决办法是使用键值对。
onExpand = (expanded, record) = { const { dispatch } = this.pro凡科抠图; if (expanded === false) { // 因为如果不断的添加键值对,会造成数据过于庞大,浪费资源, // 因此在每次合并的时候讲相应键值下的数据清空 console.log("合并!"); this.setState({ subTabData: { ...this.state.subTabData, [record.contract_id]: [] , } else { console.log("展开!"); dispatch({ type: 'flow/getPlanList', payload: { contractId: record.contract_id, callback: () = { const { flow: { data }, } = this.pro凡科抠图; this.setState({ subTabData: { ...this.state.subTabData, [record.contract_id]: data.list , console.log("返回数据(PlanList):" + JSON.stringify(this.state.subTabData)); }
以上这篇React Ant Design树形表格的复杂增删改操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持凡科。
React Ant Design树型报表的繁杂删改改实际操作 本文关键详细介绍了React Ant Design树型报表的繁杂删改改实际操作,具备非常好的参照使用价值,期待对大伙儿有一定的协助。一起追随...
2021-01-05企业技术专业从业有机废气解决行业数十年,从业SDG酸气吸咐剂,二噁英吸咐专用型粉末状状特异性炭和工业生产有机化学有机废气解决用的蜂窝状特异性炭等一系列产品吸咐剂的市场...
2021-01-05招聘人数:15职位信息
广州凡科互联网科技股份有限公司(简称凡科,股票代码:832828)由四位曾任职于百度、腾讯的80后于2010年10月创立,是一家专注为中小企业提供...
2021-01-05招聘人数:19职位信息
广州凡科互联网科技股份有限公司(简称凡科,股票代码:832828)由四位曾任职于百度、腾讯的80后于2010年10月创立,是一家专注为中小企业提供...
2021-01-05请填好详细的信息内容及要求內容、或协作意愿,大家将在第一時间与您联络;请明确您所填好的內容信息内容真正合理,大家能根据这种合理的联络方法与您联络,提高协作高效率与...
2021-01-05在目前的阶段,大部分每家企业全是有所属于本身的网站,但是基建项目企业网站建设如何才可以有一个好的具体实际效果呢?公司建网站整个过程时要注意以下几方面: ...
2021-01-05