【问题标题】:How to get overall error status on Material UI DataGrid?如何获取 Material UI DataGrid 的整体错误状态?
【发布时间】:2022-01-23 00:09:56
【问题描述】:

我正在使用 Material UI DataGrid 组件来呈现 EXCEL 文件。每个 Excel 文件都有多个列名称并具有特定的类型。例如:

const columns = [
    {
        "field": "uwgroup",
        "headerName": "Group",
        "minWidth": 200,
        "editable": true
    },
    {
        "field": "Amazing column Name ",
        "flex": 1,
        "minWidth": 150,
        "editable": true
    },
    {
        "field": "Building TSI",
        "type": 'number',
        "flex": 1,
        "minWidth": 150,
        "editable": true
    },
    {
        "field": "dev",
        "flex": 1,
        "minWidth": 150,
        "editable": true
    }
]

列名称Building TSI 的类型为number。我正在使用cellClassName 添加类名invalid,类似于:

classnames({
   invalid: !isPositiveNumber(params.value)
})

它工作正常并呈现类名并指示错误单元格。问题是,我想计算错误单元格的总数。原因是,我们只允许在任何单元格中没有错误的情况下将网格值保存到数据库中。

解决方案,目前我已经尝试过:

  1. errorCount 添加状态并在我添加类时增加errorCount。这会导致多次重新渲染并超出内存限制。
  2. 我尝试使用document.getElementByClassNames('invalid') 并检查它的长度。它仅适用于渲染项目。也就是说,如果excel文件超过10行,则进行分页。无效单元格计数仅针对当前呈现的页面进行。
  3. 我尝试使用preProcessEditCellProps 道具来指示错误。但是,我无论如何都找不到获得错误单元格的总数。唯一能让我摆脱这个道具的是不允许用户输入错误值的能力。
  4. 我什至尝试过使用localStorage。它与解决方案 2 具有完全相同的问题。

如果有人遇到过类似情况,我将不胜感激。获得总体错误单元格计数会很好,因此,我可以启用以禁用 SAVE 按钮。

我遇到的一个限制是 excel 文件很大,平均包含 30-40k 行和 25-40 列。为每个单元格添加状态会降低性能。

提前致谢!

【问题讨论】:

  • 根据我从问题中了解到的情况,您在设置之前已经准备好了 DataGrid 的数据,您可以像const hasError = data.find((x) => !isPositiveNumber(x.tsi)) !== undefined 一样简单地过滤之前的数据对象,并为导出设置禁用状态按钮,如果不是这种情况,请详细说明如何让数据显示在 DataGrid 中
  • @RicardoDiasMorais,我明白你的意思。我在使用这种方法时遇到了 2 个问题。 1)我有超过 15-30 个预定义的列和不同的规则。我做了类似hasIntegerTypeErrorhasEnumTypeError 的事情。 2) 因为,我必须检查事件更改的错误(例如列编辑、列删除、列重命名),所以我增加或减少了 MUI DataGrid 的 onStateChange 道具上的状态。它会导致多次渲染,最后通过说达到最大渲染来保释。这种方法是我最初的方法。
  • 您可以为特定行的“错误状态”添加一个额外的布尔列hide: true,(ps:在fieldsexport options 属性中定义要导出的列),其中该列的值是真/假,具体取决于该行的所有其他列是否正确,然后,在 DataGrid 数据上,如果任何行的隐藏列错误为真,则禁用导出按钮
  • 老实说,这并不能真正扩展。我的 Excel 文件很大,平均有 30-40k 行和 15-30 列。这意味着,我最终将拥有 2 倍数量的单元格。我想,我找到了一个 hacky 方法,我会发布我的答案,以防万一有人需要它。
  • 当您有 30-40k 行时很难扩展,您需要验证每个列中的所有列是否正确,更不用说它们也是可编辑的。我认为如果导出按钮始终可用会更好,并且在导出时,验证所有内容是否正确,如果不正确,请向用户提供一些错误所在的信息。另外,我没有说每个列有 1 个以上的单元格,但只有 1 个额外的单元格可以验证所有其他单元格,就像我提到的那样,您在 export options 上有字段道具

标签: javascript material-ui material-ui-x


【解决方案1】:

在列中包含另一个属性并在导出每个单元格/行之前引用它会有所帮助。

在此示例中,使用列定义和实际数据作为参数调用合格ForExport 函数将给出一个布尔值,说明是否存在错误。也可以更改为计数错误。

const isInvalidBuildingTSI=(value)=>!isPositiveNumber(value);

const isPositiveNumber=(num)=>num>=0;

const eligibleForExport=(columns,data)=>{
    return !(data.find(row=>columns.find(column=>row[column.field] 
        && typeof column["isValid"] === "function" && column["isValid"](row[column.field]))))
}

const columns = [
    {
        "field": "uwgroup",
        "headerName": "Group",
        "minWidth": 200,
        "editable": true
    },
    {
        "field": "Building TSI",
        "type": 'number',
        "flex": 1,
        "minWidth": 150,
        "editable": true,
        "isValid" : isInvalidBuildingTSI,
        "cellClassName":isInvalidBuildingTSI(param.value)?"invalid":""
    }
];

【讨论】:

  • 这类似于@Ricardo Dias Morais 提供的第一条评论。说实话并没有帮助。我找到了一个修复程序,并将创建一个沙箱和链接作为答案。这可能对某人有帮助。使用沙盒更容易发现问题。
【解决方案2】:

如果初始数据始终有效,解决您的问题的一种简单方法是遵循有关客户端验证的 DataGrid 文档:

客户端验证?

要验证单元格中的值,首先添加一个 preProcessEditCellProps 回调到column definition 的 要验证的字段。调用后,验证提供的值 在params.props.value。然后,返回一个包含的新对象 params.props 以及 error 属性设置为 true 或 false。如果 error 属性为真,该值将永远不会被提交。

const columns: GridColDef[] = [
  {
    field: 'firstName',
    preProcessEditCellProps: (params: GridEditCellPropsChangeParams) => {
      const hasError = params.props.value.length < 3;
      return { ...params.props, error: hasError };
    },
  },
];

对于您的方案,这将导致以下结果:

const columns = [
    {
        "field": "uwgroup",
        "headerName": "Group",
        "minWidth": 200,
        "editable": true
    },
    {
        "field": "Amazing column Name ",
        "flex": 1,
        "minWidth": 150,
        "editable": true
    },
    {
        "field": "Building TSI",
        "type": 'number',
        "flex": 1,
        "minWidth": 150,
        "editable": true,
        preProcessEditCellProps(params) {
            const invalid = !isPositiveNumber(params.props.value);
            return { ...params.props, error: invalid };
        }
    },
    {
        "field": "dev",
        "flex": 1,
        "minWidth": 150,
        "editable": true
    }
]

与您目前拥有的有一个重要的区别。此验证仅影响编辑。所以初始数据必须是有效的。优点是您不再需要使用classnames({ invalid: !isPositiveNumber(params.value) }),并且可以始终启用保存按钮,因为可以假定所有提交的更改都是有效的。

如果初始数据可能无效,这可能不是您要寻找的答案。

【讨论】:

  • 我的初始数据可能无效。正如preProcessEditCellProps 的文档中所说,如果单元格值无效,它将永远不会被提交。我仍然希望用户输入不正确的值,但突出显示为错误单元格。这种要求来自业务方面。
猜你喜欢
  • 2021-10-08
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 2022-08-12
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
相关资源
最近更新 更多