单击行材料-ui DataGrid内的按钮时如何设置行数据?
Posted
技术标签:
【中文标题】单击行材料-ui DataGrid内的按钮时如何设置行数据?【英文标题】:How to set row data when clicking button inside the row material-ui DataGrid? 【发布时间】:2021-07-20 05:21:38 【问题描述】:我有一个 Material-UI DataGrid 组件,它有一个连续的编辑和删除按钮,但我只能做警报或控制台日志,
为什么会有按钮在一行,因为点击按钮时需要对话框,例如当用户点击删除按钮时会有一个删除操作的确认对话框,或者当点击一个编辑按钮时会有一个表单对话框更新行,
需要推送用户同时只编辑或删除一项。所以不允许多选。
我的问题是如何在点击列定义内的按钮时获取组件中的行数据,在这种情况下,点击Edit
或Delete
按钮。
使用"@material-ui/data-grid": "^4.0.0-alpha.26"
import Container from "@material-ui/core/Container";
import Grid from "@material-ui/core/Grid";
import Paper from "@material-ui/core/Paper";
import DeleteIcon from "@material-ui/icons/Delete";
import EditIcon from "@material-ui/icons/Edit";
import Button from "@material-ui/core/Button";
import AddIcon from "@material-ui/icons/Add";
import makeStyles from "@material-ui/core/styles";
import
DataGrid,
GridColDef,
GridApi,
GridCellValue
from "@material-ui/data-grid";
const columns: GridColDef[] = [
field: "id", headerName: "ID", width: 70 ,
field: "name", headerName: "First name", width: 130 ,
field: "surname", headerName: "Last name", width: 130 ,
field: "edit",
headerName: "Edit",
sortable: false,
width: 130,
disableClickEventBubbling: true,
renderCell: (params) =>
const onClick = () =>
const api: GridApi = params.api;
const fields = api
.getAllColumns()
.map((c) => c.field)
.filter((c) => c !== "__check__" && !!c);
const thisRow: Record<string, GridCellValue> = ;
fields.forEach((f) =>
thisRow[f] = params.getValue(f);
);
// set to state rather then alert
return alert(JSON.stringify(thisRow, null, 4));
;
return (
<Button
variant="contained"
color="primary"
startIcon=<EditIcon />
onClick=onClick
>
Edit
</Button>
);
,
field: "delete",
headerName: "Delete",
sortable: false,
width: 130,
disableClickEventBubbling: true,
renderCell: (params) =>
const onClick = () =>
const api: GridApi = params.api;
const fields = api
.getAllColumns()
.map((c) => c.field)
.filter((c) => c !== "__check__" && !!c);
const thisRow: Record<string, GridCellValue> = ;
fields.forEach((f) =>
thisRow[f] = params.getValue(f);
);
// set to state rather then alert
return alert(JSON.stringify(thisRow, null, 4));
;
return (
<Button
variant="contained"
color="secondary"
startIcon=<DeleteIcon />
onClick=onClick
>
Delete
</Button>
);
];
const rows = [
id: 1, name: "Example 1", surname: "example" ,
id: 2, name: "Example 2", surname: "example"
];
export type User =
id: number;
name: string;
surname: string;
;
const useStyles = makeStyles((theme) => (
content:
flexGrow: 1,
height: "100vh",
overflow: "auto"
,
appBarSpacer: theme.mixins.toolbar,
container:
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4)
,
paper:
padding: theme.spacing(2),
display: "flex",
overflow: "auto",
flexDirection: "column",
elevation: 3
));
const App = () =>
const classes = useStyles();
return (
<main className=classes.content>
<div className=classes.appBarSpacer />
<Container maxWidth="lg" className=classes.container>
<Grid item xs=12>
<Paper className=classes.paper>
<DataGrid
rows=rows
columns=columns
pageSize=10
columnBuffer=8
autoHeight
/>
</Paper>
</Grid>
<Grid item xs=3 style= padding: 20 >
<Button
variant="contained"
color="primary"
startIcon=<AddIcon />
onClick=() =>
console.log("new");
>
New
</Button>
</Grid>
</Container>
</main>
);
;
export default App;
【问题讨论】:
我想知道Dialog组件在哪里。 您没有在renderCell
中放置任何对话框组件。
@Medi 如果没有实现和按需显示/隐藏,就无法打开对话框。
对不起,我稍后会添加对话框组件。但现在我只想设置状态,然后我可以将任何想要的组件传递给它。
【参考方案1】:
DataGrid
组件有一个 prop onCellClick
来处理用户单击数据网格中的任何单元格时的事件。该道具使用GridCellParams
类型,只需要根据GridCellParams.colDef.field
属性过滤列即可。
代码修改如下;
编辑:根据Material-UI documentation,GridCellParams 属性getValue
刚刚更改。现在它需要两个参数; getValue(id: GridRowId, field: string)
import Container from "@material-ui/core/Container";
import Grid from "@material-ui/core/Grid";
import Paper from "@material-ui/core/Paper";
import DeleteIcon from "@material-ui/icons/Delete";
import EditIcon from "@material-ui/icons/Edit";
import Button from "@material-ui/core/Button";
import makeStyles from "@material-ui/core/styles";
import
DataGrid,
GridColDef,
GridApi,
GridCellValue,
GridCellParams
from "@material-ui/data-grid";
import React, useState from "react";
import
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions
from "@material-ui/core";
const columns: GridColDef[] = [
field: "id", headerName: "ID", width: 70 ,
field: "name", headerName: "First name", width: 130 ,
field: "surname", headerName: "Last name", width: 130 ,
field: "edit",
headerName: "Edit",
sortable: false,
width: 130,
disableClickEventBubbling: true,
renderCell: () =>
return (
<Button variant="contained" color="primary" startIcon=<EditIcon />>
Edit
</Button>
);
,
field: "delete",
headerName: "Delete",
sortable: false,
width: 130,
disableClickEventBubbling: true,
renderCell: () =>
return (
<Button
variant="contained"
color="secondary"
startIcon=<DeleteIcon />
>
Delete
</Button>
);
];
const rows = [
id: 1, name: "Example 1", surname: "example" ,
id: 2, name: "Example 2", surname: "example"
];
export type User =
id: number;
name: string;
surname: string;
;
const useStyles = makeStyles((theme) => (
content:
flexGrow: 1,
height: "100vh",
overflow: "auto"
,
appBarSpacer: theme.mixins.toolbar,
container:
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4)
,
paper:
padding: theme.spacing(2),
display: "flex",
overflow: "auto",
flexDirection: "column",
elevation: 3
));
const App = () =>
const classes = useStyles();
const [selectedUser, setSelectedUser] = useState( as User);
const [openDialog, setOpenDialog] = useState(false);
function currentlySelected(params: GridCellParams)
const api: GridApi = params.api;
const value = params.colDef.field;
if (!(value === "edit" || value === "delete"))
return;
const fields = api
.getAllColumns()
.map((c) => c.field)
.filter((c) => c !== "__check__" && !!c);
const thisRow: Record<string, GridCellValue> = ;
fields.forEach((f) =>
thisRow[f] = params.getValue(params.id, f);
);
const user = as User;
user["id"] = Number(thisRow["id"]);
user["name"] = thisRow["name"]!.toString();
user["surname"] = thisRow["surname"]!.toString();
setSelectedUser(user);
setOpenDialog(true);
const handleClose = () =>
setOpenDialog(false);
;
return (
<main className=classes.content>
<div className=classes.appBarSpacer />
<Container maxWidth="lg" className=classes.container>
<Grid item xs=12>
<Paper className=classes.paper>
<DataGrid
rows=rows
columns=columns
pageSize=10
columnBuffer=8
autoHeight
onCellClick=currentlySelected
/>
</Paper>
</Grid>
</Container>
<Dialog
open=openDialog
onClose=handleClose
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title"> User </DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
JSON.stringify(selectedUser)
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick=handleClose color="primary">
Cancel
</Button>
<Button onClick=handleClose color="primary">
Confirm
</Button>
</DialogActions>
</Dialog>
</main>
);
;
export default App;
【讨论】:
更新您现有的问题。 这是您问题的答案吗? 是的,完全正确。你可能误解了这个问题。 从打字稿中,我现在遇到了一些错误(06/08/2021)。也许这是一个过时的答案。 @hfontanez 我编辑了链接,现在可以使用了。【参考方案2】:更新 - 2021 年
06/08/2021 - 最新答案
以下内容按预期对我有用。
const columns: GridColDef[] = [
field: 'id', headerName: 'ID', width: 100, hide: true ,
field: 'action',
width: 130,
sortable: false,
renderCell: (params) =>
const onClickDelete = async () =>
return alert(JSON.stringify(params.row, null, 4));
;
const onClickEdit = async () => ;
return (
<>
<IconButton color="secondary" onClick=onClickDelete>
<DeleteIcon />
</IconButton>
<IconButton color="secondary" onClick=onClickEdit>
<EditIcon />
</IconButton>
</>
);
,
,
【讨论】:
以上是关于单击行材料-ui DataGrid内的按钮时如何设置行数据?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用reactjs和material ui删除表格内的特定文本字段