antd可展开单元格实现按需可展开
每次起一个文章名字的时候都很头疼,不知道怎么描述才算得上直截了当,直奔主题。
功能的使用场景
具体使用场景可以参考下图,当时失败原因下菜品多余一个时,当前行可展开;当仅有一个菜品时,当前行不可展开。
解决思路
antd table要用到的属性
- expandedRowRender:额外的展开行属性,类型是个方法或者ReactNode
- rowClassName:设置行的class名称
解决方案
- 既然是可展开行,必然要使用expandedRowRender属性,在expandedRowRender里面返回一个新的table,用来承载多个菜品名称。
- 菜品名称数组里的第一个菜品在当前行展示,其余的在展开的table里显示。
- 如果只有一个菜品,则不需要可展开行。
存在的问题
表格渲染时已经将expandedRowRender属性渲染出来,即便是方法返回一个null或者false,当前行还是会有一个可展开按钮,点一个会有一行空白的表格。
解决问题
这种问题首先想到的是去看看源码这部分是怎么实现的,看看有什么方法能够解决,果然有发现:
里面去table里面设置expandIconAsCell为false,期待页面有所变化,结果并没有卵用。
哪能怎么办呢?
最笨的方法吧:我把可点击的那个展开按钮隐藏掉,没有按钮你还咋点,哈哈哈!
问题2.0
可展开行按钮是在行的维度渲染的,从那里去控制依据当前行菜品数组的长度来控制当前行的样式呢?
解决问题2.0
- 脑洞打开,我要是能用css样式查询到父级,隐掉当前的样式布局不就好了吗?立马去查一下有没有方法,哈哈哈原来想要这种方法的不止我一个,有方法,但是最快要到css4。目前浏览器都还没用做支持。
- jquery能查到,这方法保留吧,想想还有吗?
- 去翻翻文档,看看table有没有方法能拿到每条记录的值,并且执行结果还不会有比较严重的后果(要求不高,展示正常就行)。于是发现了
rowClassName
,没想到它除了支持string居然还可以是function(record, index),文档还是不熟悉啊,呜呜呜。
解决方案
通过rowClassName
的方法判断当前行是否需要展开设置样式,不可展开的设置class名称为"noExpand"。
看代码吧!
const failurecolumns = [
{
title: '失败原因',
dataIndex: 'failureReason',
key: 'failureReason',
},
{
title: '菜谱名称',
dataIndex: 'pubitemNameList',
key: 'pubitemNameList',
render: text => text[0],
},
];
const failedCol = [{
key: 'null',
render: () => '',
width: '50%',
}, {
key: 'dishName',
render: record => record,
}];
const tableProps = path === 'failure' ?
{
expandedRowRender: record =>
(record.pubitemNameList.length > 1 ? <Table
dataSource={_.drop(record.pubitemNameList)}
pagination={false}
columns={failedCol}
showHeader={false}
rowKey={i => i}
/> : null),
} : {};
return (
<Table
{...tableProps}
dataSource={storeList}
columns={failurecolumns}
pagination={storePage}
onChange={page => onPageModal(page)}
rowKey={record => `${record.id}${Math.random()}`}
rowClassName={record => record.pubitemNameList && record.pubitemNameList.length === 1 && 'noExpand'}
/>
);
less文件:
// 可展开单元格无可展开项时
.noExpand {
.ant-table-row-expand-icon {
display: none;
}
}
总结
功能实现起来不太困难,但是方法也不太优雅。如果文档更熟悉一点的话,这问题肯能解决的更快一些。