gpt4 book ai didi

reactjs - 处理ag网格 react 并渲染复选框网格

转载 作者:行者123 更新时间:2023-12-03 13:22:38 25 4
gpt4 key购买 nike

我正在搞乱 ag-grid、react-apollo,一切似乎都工作正常。这里的目标是单击复选框并发生突变/网络请求来修改某些数据。我遇到的问题是,它会重新绘制整行,这可能非常慢,但我实际上只是尝试更新单元格本身,以便它快速且用户体验更好。我的一个想法是进行乐观更新并更新我的缓存/利用我的缓存。你们采取了哪些方法。

列和行数据都是通过 apollo 查询获取的。

这是一些代码:

复选框渲染器

import React, { Component } from "react";
import Checkbox from "@material-ui/core/Checkbox";
import _ from "lodash";

class CheckboxItem extends Component {
constructor(props) {
super(props);
this.state = {
value: false
};
this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
}

componentDidMount() {
this.setDefaultState();
}

setDefaultState() {
const { data, colDef, api } = this.props;
const { externalData } = api;
if (externalData && externalData.length > 0) {
if (_.find(data.roles, _.matchesProperty("name", colDef.headerName))) {
this.setState({
value: true
});
}
}
}

updateGridAssociation(checked) {
const { data, colDef } = this.props;
// const { externalData, entitySpec, fieldSpec } = this.props.api;
// console.log(data);
// console.log(colDef);
if (checked) {
this.props.api.assign(data.id, colDef.id);
return;
}
this.props.api.unassign(data.id, colDef.id);
return;
}

handleCheckboxChange(event) {
const checked = !this.state.value;
this.updateGridAssociation(checked);
this.setState({ value: checked });
}

render() {
return (
<Checkbox
checked={this.state.value}
onChange={this.handleCheckboxChange}
/>
);
}
}

export default CheckboxItem;

网格本身:

import React, { Component } from "react";
import { graphql, compose } from "react-apollo";
import gql from "graphql-tag";
import Grid from "@material-ui/core/Grid";
import _ from "lodash";
import { AgGridReact } from "ag-grid-react";
import { CheckboxItem } from "../Grid";
import "ag-grid/dist/styles/ag-grid.css";
import "ag-grid/dist/styles/ag-theme-material.css";

class UserRole extends Component {
constructor(props) {
super(props);
this.api = null;
}

generateColumns = roles => {
const columns = [];
const initialColumn = {
headerName: "User Email",
editable: false,
field: "email"
};
columns.push(initialColumn);
_.forEach(roles, role => {
const roleColumn = {
headerName: role.name,
editable: false,
cellRendererFramework: CheckboxItem,
id: role.id,
suppressMenu: true,
suppressSorting: true
};
columns.push(roleColumn);
});
if (this.api.setColumnDefs && roles) {
this.api.setColumnDefs(columns);
}
return columns;
};

onGridReady = params => {
this.api = params.api;
this.columnApi = params.columnApi;
this.api.assign = (userId, roleId) => {
this.props.assignRole({
variables: { userId, roleId },
refetchQueries: () => ["allUserRoles", "isAuthenticated"]
});
};

this.api.unassign = (userId, roleId) => {
this.props.unassignRole({
variables: { userId, roleId },
refetchQueries: () => ["allUserRoles", "isAuthenticated"]
});
};
params.api.sizeColumnsToFit();
};

onGridSizeChanged = params => {
const gridWidth = document.getElementById("grid-wrapper").offsetWidth;
const columnsToShow = [];
const columnsToHide = [];
let totalColsWidth = 0;
const allColumns = params.columnApi.getAllColumns();
for (let i = 0; i < allColumns.length; i++) {
const column = allColumns[i];
totalColsWidth += column.getMinWidth();
if (totalColsWidth > gridWidth) {
columnsToHide.push(column.colId);
} else {
columnsToShow.push(column.colId);
}
}
params.columnApi.setColumnsVisible(columnsToShow, true);
params.columnApi.setColumnsVisible(columnsToHide, false);
params.api.sizeColumnsToFit();
};

onCellValueChanged = params => {};

render() {
console.log(this.props);
const { users, roles } = this.props.userRoles;
if (this.api) {
this.api.setColumnDefs(this.generateColumns(roles));
this.api.sizeColumnsToFit();
this.api.externalData = roles;
this.api.setRowData(_.cloneDeep(users));
}
return (
<Grid
item
xs={12}
sm={12}
className="ag-theme-material"
style={{
height: "80vh",
width: "100vh"
}}
>
<AgGridReact
onGridReady={this.onGridReady}
onGridSizeChanged={this.onGridSizeChanged}
columnDefs={[]}
enableSorting
pagination
paginationAutoPageSize
enableFilter
enableCellChangeFlash
rowData={_.cloneDeep(users)}
deltaRowDataMode={true}
getRowNodeId={data => data.id}
onCellValueChanged={this.onCellValueChanged}
/>
</Grid>
);
}
}

const userRolesQuery = gql`
query allUserRoles {
users {
id
email
roles {
id
name
}
}

roles {
id
name
}
}
`;

const unassignRole = gql`
mutation($userId: String!, $roleId: String!) {
unassignUserRole(userId: $userId, roleId: $roleId) {
id
email
roles {
id
name
}
}
}
`;

const assignRole = gql`
mutation($userId: String!, $roleId: String!) {
assignUserRole(userId: $userId, roleId: $roleId) {
id
email
roles {
id
name
}
}
}
`;

export default compose(
graphql(userRolesQuery, {
name: "userRoles",
options: { fetchPolicy: "cache-and-network" }
}),
graphql(unassignRole, {
name: "unassignRole"
}),
graphql(assignRole, {
name: "assignRole"
})
)(UserRole);

enter image description here

最佳答案

我不知道 ag-grid,但是......在这种情况下发出请求会导致整个网格(UserRole 组件)重绘

当您传递影响整个父状态的操作(给子级)时,这是正常的(新数据到达 props => 重绘)。

您可以通过 shouldComponentUpdate() 来避免这种情况 - 例如仅当行数发生变化时才重绘。

但是还有另一个问题 - 您正在进行乐观的更改(更改复选框状态) - 如果突变失败怎么办?您必须处理 Apollo 错误并强制重绘整个网格 - 更改是本地的(单元格)。这可以通过 f.e. 完成。通过在 shouldComponentUpdate 中设置标志(使用 setState)和附加条件。

关于reactjs - 处理ag网格 react 并渲染复选框网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51490792/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com