如何通过单击 mui 中的外部按钮来过滤 DataGrid 列

qui*_*ode 5 javascript reactjs material-ui

假设我有一个像这样的数据网格表(来自官方 MUI 文档):

import * as React from 'react';
import { DataGrid, GridToolbar } from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';

const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin'];

export default function ControlledFilters() {
  const { data } = useDemoData({
    dataSet: 'Employee',
    visibleFields: VISIBLE_FIELDS,
    rowLength: 100,
  });

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        {...data}
        components={{
          Toolbar: GridToolbar,
        }}
      />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

现在假设我想通过按钮的 onClick 过滤此表中的“名称”列。单击该按钮时,应该给出一个字符串,比如说“Ray”。单击此按钮时,我想自动过滤表,以便仅显示“名称”列中包含字符串“Ray”的每个值。

到目前为止我的方法

我尝试使用useStatefrom React 和filterModelDataGrid 中的 prop,以便按下按钮可以过滤表,如下所示:

  ....

  const [filt, setFilt] = useState('') // Initialize it with an empty filter
  const handleClick = () => {
      setFilt('Ray');
  };

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        {...data}
        components={{
          Toolbar: GridToolbar,
        }}
        filterModel={{
          items: [{ columnField: 'name', operatorValue: 'contains', value: filt },
          ]
        }}
      />

    <Button onClick={handleClick}>Change Filter</Button>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

这是可行的,但这种方法的问题是它锁定了所有其他过滤器,并且过滤器基本上卡在“名称”列上,用户现在只能使用按钮来过滤该列。它甚至不让我移除过滤器。

我也尝试过这个onFilterModelChange道具,但没有用;老实说,我对如何在这个特定情况下使用它感到困惑。任何帮助,将不胜感激。

Car*_*lin 5

你很接近。我相信您需要形成整个items数组,而不是仅过滤器对象的一部分。

setFilt([{ columnField: 'name', operatorValue: 'contains', value: "Ray"}])即而不是setFilt("Ray"){ columnField: 'name', operatorValue: 'contains', value: filt}

对于 MUIv5


items: []您可以通过在 中设置来重置过滤器filterModel

具有单个过滤条件的CodeSandbox 示例。

(如果你在codesandbox上遇到任何编译问题,我必须安装@mui/material v5.9.2而不是v5.9.3让它工作)

const [filt, setFilt] = useState([])

<DataGrid 
  {...data} 
  filterModel={{
    items: filt
  }}
/>
<Button
  onClick={() =>
    setFilt([
      {
        columnField: "name",
        operatorValue: "startsWith",
        value: "A"
      }
     ])
  }
>
  Name Starts With A
</Button>
<Button
  onClick={() => setFilt([])}
>
  Reset Filters
</Button>
Run Code Online (Sandbox Code Playgroud)

奖励:使用按钮进行多重过滤

CodeSandbox带按钮的多过滤器网格示例。

多重过滤仅适用于MUI 专业版。如果没有专业版,则在第一个过滤器之后添加的任何其他过滤器都将被忽略(正如您所发现的)。

这就是我想出的方法,使用@mui/x-data-grid-pro3 个不同的按钮,每个按钮应用一个独特的过滤器:

const [filt, setFilt] = useState([])

<DataGrid 
  {...data} 
  filterModel={{
    items: filt
  }}
/>
<Button
  onClick={() =>
    setFilt([
      {
        columnField: "name",
        operatorValue: "startsWith",
        value: "A"
      }
     ])
  }
>
  Name Starts With A
</Button>
<Button
  onClick={() => setFilt([])}
>
  Reset Filters
</Button>
Run Code Online (Sandbox Code Playgroud)

需要注意的一点是——使用多重过滤时,您需要id向数组中的每个过滤器对象添加一个。items

例如

[
  { id: 1, columnField: 'rating', operatorValue: '>', value: 3 },
  { id: 2, columnField: 'name', operatorValue: 'startsWith', value: "A" }
]
Run Code Online (Sandbox Code Playgroud)

请记住此代码不再实时工作

更新:现在你必须使用onFilterModelChange

const [filt, setFilt] = useState({
    items: [{
    }]

  })

<DataGrid 
  {...data} 
  filterModel={filt}
   onFilterModelChange={(newFilterModel) =>
     setFilt(newFilterModel)
   }
/>
<Button
  onClick={() =>
    setFilt([
      {
        columnField: "name",
        operatorValue: "startsWith",
        value: "A"
      }
     ])
  }
>
  Name Starts With A
</Button>
<Button
  onClick={() => setFilt([])}
>
  Reset Filters
</Button>
Run Code Online (Sandbox Code Playgroud)

使用onFilterModalChangeprops,您可以更新表过滤器。