我正在使用Material-UI在react中创建一个虚拟表。在每一行的最后一列中,应该有一个按钮来扩展该特定行。我知道如何进行行的扩展,但是我还没有弄清楚如何正确添加按钮。
我正在尝试将其集成到文档提供的虚拟表的示例中,确切的代码如下:https://material-ui.com/components/tables/。但是,由于此示例提供了一个通用功能来创建所有数据单元,并且由于我认为我无法访问特定行的索引,因此我不知道如何添加实际按钮。
import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { withStyles } from '@material-ui/core/styles';
import TableCell from '@material-ui/core/TableCell';
import Paper from '@material-ui/core/Paper';
import { AutoSizer, Column, Table } from 'react-virtualized';
const styles = theme => ({
flexContainer: {
display: 'flex',
alignItems: 'center',
boxSizing: 'border-box',
},
tableRow: {
cursor: 'pointer',
},
tableRowHover: {
'&:hover': {
backgroundColor: theme.palette.grey[200],
},
},
tableCell: {
flex: 1,
},
noClick: {
cursor: 'initial',
},
});
class MuiVirtualizedTable extends React.PureComponent {
static defaultProps = {
headerHeight: 48,
rowHeight: 48,
};
getRowClassName = ({ index }) => {
const { classes, onRowClick } = this.props;
return clsx(classes.tableRow, classes.flexContainer, {
[classes.tableRowHover]: index !== -1 && onRowClick != null,
});
};
cellRenderer = ({ cellData, columnIndex }) => {
const { columns, classes, rowHeight, onRowClick } = this.props;
return (
<TableCell
component="div"
className={clsx(classes.tableCell, classes.flexContainer, {
[classes.noClick]: onRowClick == null,
})}
variant="body"
style={{ height: rowHeight }}
align={(columnIndex != null && columns[columnIndex].numeric) || false ? 'right' : 'left'}
>
{cellData}
</TableCell>
);
};
headerRenderer = ({ label, columnIndex }) => {
const { headerHeight, columns, classes } = this.props;
return (
<TableCell
component="div"
className={clsx(classes.tableCell, classes.flexContainer, classes.noClick)}
variant="head"
style={{ height: headerHeight }}
align={columns[columnIndex].numeric || false ? 'right' : 'left'}
>
<span>{label}</span>
</TableCell>
);
};
render() {
const { classes, columns, ...tableProps } = this.props;
return (
<AutoSizer>
{({ height, width }) => (
<Table height={height} width={width} {...tableProps} rowClassName={this.getRowClassName}>
{columns.map(({ dataKey, ...other }, index) => {
return (
<Column
key={dataKey}
headerRenderer={headerProps =>
this.headerRenderer({
...headerProps,
columnIndex: index,
})
}
className={classes.flexContainer}
cellRenderer={this.cellRenderer}
dataKey={dataKey}
{...other}
/>
);
})}
</Table>
)}
</AutoSizer>
);
}
}
MuiVirtualizedTable.propTypes = {
classes: PropTypes.object.isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
headerHeight: PropTypes.number,
onRowClick: PropTypes.func,
rowHeight: PropTypes.number,
};
const VirtualizedTable = withStyles(styles)(MuiVirtualizedTable);
// ---
const sample = [
['Frozen yoghurt', 159, 6.0, 24, 4.0],
['Ice cream sandwich', 237, 9.0, 37, 4.3],
['Eclair', 262, 16.0, 24, 6.0],
['Cupcake', 305, 3.7, 67, 4.3],
['Gingerbread', 356, 16.0, 49, 3.9],
];
function createData(id, dessert, calories, fat, carbs, protein) {
return { id, dessert, calories, fat, carbs, protein };
}
const rows = [];
for (let i = 0; i < 200; i += 1) {
const randomSelection = sample[Math.floor(Math.random() * sample.length)];
rows.push(createData(i, ...randomSelection));
}
function ReactVirtualizedTable() {
return (
<Paper style={{ height: 400, width: '100%' }}>
<VirtualizedTable
rowCount={rows.length}
rowGetter={({ index }) => rows[index]}
columns={[
{
width: 200,
label: 'Dessert',
dataKey: 'dessert',
},
{
width: 120,
label: 'Calories\u00A0(g)',
dataKey: 'calories',
numeric: true,
},
{
width: 120,
label: 'Fat\u00A0(g)',
dataKey: 'fat',
numeric: true,
},
{
width: 120,
label: 'Carbs\u00A0(g)',
dataKey: 'carbs',
numeric: true,
},
{
width: 120,
label: 'Protein\u00A0(g)',
dataKey: 'protein',
numeric: true,
},
]}
/>
</Paper>
);
}
export default ReactVirtualizedTable;