【问题标题】:Material-UI DataGrid/DataGridPro: How to persist state of columns through re-render, when you change their visibility with DataGrid Column ToolbarMaterial-UI DataGrid/DataGridPro:当您使用 DataGrid Column Toolbar 更改其可见性时,如何通过重新渲染来保持列的状态
【发布时间】:2022-01-05 15:46:51
【问题描述】:

我们在基于 React 的项目中使用 MUI DataGrid。

目前,在使用 DataGrid 的工具栏列菜单切换某些列的可见性后,我正在尝试保存/保持列的状态,因为目前在重新渲染后它已恢复为默认列设置。

我想知道如何访问 DataGrid 的状态/DataGrid 中列的可见性状态,以便以后调整/保存/重用它?

到目前为止,我对 apiRef 做了一些改动,但我从 apiRef.current 得到的只是空对象。我在下面添加了一些基本的 codeSandbox 示例来展示我是如何尝试访问它的。

https://codesandbox.io/s/datagridprodemo-material-demo-forked-189j9?file=/demo.js


也许有更好/不同的方法,或者我只需要以某种方式创建状态。我们希望将来可能将列的状态作为用户偏好保留,因此这对于实现这一点至关重要。

欢迎所有建议,我先谢谢你。

【问题讨论】:

    标签: javascript reactjs material-ui datagrid


    【解决方案1】:

    幸运的是,DataGrid API 提供了 columnVisibilityModelonColumnVisibilityChange 属性。

    有关控制columnVisibilityModel 的简单示例,请参见此代码沙箱:https://codesandbox.io/s/mui-datagrid-oncolumnvisibilitychange-savestate-u1opzc?file=/src/App.tsx:1960-1984

    这是一个简单实现的代码。您的初始状态可能会有所不同。另外,请注意,除非 columnVisibilityModel 最初未定义,否则我无法弄清楚如何让 DataGridPro 调用 onColumnVisibilityChange。 Bug,还是我的错误,我不确定。

    import "./styles.css";
    import React from "react";
    import {
      DataGrid,
      GridRowsProp,
      GridColDef,
      GridCallbackDetails,
      MuiEvent,
      GridColumnVisibilityModel,
      GridColumnVisibilityChangeParams
    } from "@mui/x-data-grid";
    import { Button } from "@mui/material";
    
    const rows: GridRowsProp = [
      { id: 1, col1: "Hello", col2: "World" },
      { id: 2, col1: "DataGridPro", col2: "is Awesome" },
      { id: 3, col1: "MUI", col2: "is Amazing" }
    ];
    
    const columns: GridColDef[] = [
      { field: "col1", headerName: "Column 1", width: 150 },
      { field: "col2", headerName: "Column 2", width: 150 }
    ];
    
    const initialVisibilityModel = { col1: true, col2: true };
    
    export default function App() {
      // it is strange, but in order for DataGridPro to call onColumnVisibilityChange, columnVisibilityModel must be undefined initially
      const [
        currentGridColumnVisibilityModel,
        setCurrentGridColumnVisibilityModel
      ] = React.useState<GridColumnVisibilityModel | undefined>(undefined);
    
      const [mySavedValue, setMySavedValue] = React.useState<
        GridColumnVisibilityModel | undefined
      >(undefined);
    
      const onColumnVisibilityChange = React.useCallback(
        (
          params: GridColumnVisibilityChangeParams,
          event: MuiEvent<{}>,
          details: GridCallbackDetails
        ): void => {
          console.log("params", params);
          setCurrentGridColumnVisibilityModel((s) => ({
            // per the DataGridPro strangeness, we must marry in initial state only the first update
            ...(s ? s : initialVisibilityModel),
            [params.field]: params.isVisible
          }));
        },
        []
      );
    
      const saveACopyOfGridState = () => {
        setMySavedValue(currentGridColumnVisibilityModel || initialVisibilityModel);
      };
    
      const loadSavedCopyOfGridState = () => {
        setCurrentGridColumnVisibilityModel(mySavedValue || initialVisibilityModel);
      };
    
      const currentVisibilityAsText =
        `${Object.keys(currentGridColumnVisibilityModel ?? {}).map(
          (key) => `{${key}:${currentGridColumnVisibilityModel?.[key]}}`
        )}` || "empty";
    
      const savedVisibilityAsText =
        `${Object.keys(mySavedValue ?? {}).map(
          (key) => `{${key}:${mySavedValue?.[key]}}`
        )}` || "empty";
    
      return (
        <div style={{ height: 300, width: "100%" }}>
          <DataGrid
            rows={rows}
            columns={columns}
            columnVisibilityModel={currentGridColumnVisibilityModel}
            onColumnVisibilityChange={onColumnVisibilityChange}
          />
          <div>
            <Button onClick={saveACopyOfGridState} variant="contained">
              SAVE CURRENT COLUMN VISIBILITY STATE
            </Button>
            <Button
              onClick={loadSavedCopyOfGridState}
              variant="contained"
              color="warning"
            >
              LOAD SAVED COLUMN VISIBILITY STATE
            </Button>
          </div>
          <p>Current filter state: {currentVisibilityAsText}</p>
          <p>Saved filter state: {savedVisibilityAsText}</p>
        </div>
      );
    }

    【讨论】:

    • 谢谢您,将检查并尝试! :-)
    • 你的评论让我再次尝试我的沙盒,它有错误,所以我修复了它,现在应该可以更好地工作了
    猜你喜欢
    • 2021-10-08
    • 2020-04-29
    • 2011-08-30
    • 2021-04-29
    • 2019-01-08
    • 2013-05-13
    • 2021-08-13
    • 2021-11-19
    • 2021-05-08
    相关资源
    最近更新 更多