让 MUI 的自动完成正确显示类别和子类别

Jam*_*hys 2 autocomplete reactjs material-ui

我试图基本上实现此处找到的以下图像:

MUI 自动完成

在该主题中,他们讨论了显示类别和子类别的最佳方式,并且一致认为是 MUI 自动完成。

然而,我根本不确定如何实现这样的目标,并且希望获得一些帮助来实现它。

我需要的是用户只能选择一个类别,无论是“根类别”还是子类别。因此,在上面的示例中,要么是“Boysenberry”,要么是“Brulee Berry”。

我还想尝试获得所述类别的 id,以便我可以将其应用到我的后端(我确信我可以做到)。

我获取的 json 结构如下所示:

[
    {
        "id": 1,
        "name": "Audio Visual Equipment",
        "parent": null,
        "stockItems": [],
        "childCategories": [
            {
                "id": 2,
                "name": "Projectors",
                "stockItems": [],
                "childCategories": [
                    {
                        "id": 3,
                        "name": "Lenses",
                        "stockItems": [],
                        "childCategories": []
                    }
                ]
            }
        ]
    },
    {
        "id": 4,
        "name": "Lighting Equipment",
        "parent": null,
        "stockItems": [],
        "childCategories": [
            {
                "id": 5,
                "name": "Intelligent",
                "stockItems": [],
                "childCategories": []
            },
            {
                "id": 6,
                "name": "Generic",
                "stockItems": [],
                "childCategories": []
            },
            {
                "id": 7,
                "name": "Control",
                "stockItems": [],
                "childCategories": []
            }
        ]
    },
    {
        "id": 8,
        "name": "Sound Equipment",
        "parent": null,
        "stockItems": [],
        "childCategories": [
            {
                "id": 9,
                "name": "Mixing Desk",
                "stockItems": [],
                "childCategories": []
            }
        ]
    },
    {
        "id": 10,
        "name": "Cables",
        "parent": null,
        "stockItems": [],
        "childCategories": [
            {
                "id": 11,
                "name": "Multicore",
                "stockItems": [],
                "childCategories": []
            },
            {
                "id": 12,
                "name": "Lighting",
                "stockItems": [],
                "childCategories": []
            },
            {
                "id": 13,
                "name": "Audio",
                "stockItems": [],
                "childCategories": []
            },
            {
                "id": 14,
                "name": "Video",
                "stockItems": [],
                "childCategories": []
            },
            {
                "id": 15,
                "name": "Power",
                "stockItems": [],
                "childCategories": []
            }
        ]
    }
]
Run Code Online (Sandbox Code Playgroud)

编辑:-

当我刷新页面时,我收到以下警告:

MUI: The value provided to Autocomplete is invalid.None of the options match with `-1`.You can use the `isOptionEqualToValue` prop to customize the equality test. 
Run Code Online (Sandbox Code Playgroud)

然后,当我单击“自动完成”时,我仅获得“根”类别。当我单击其中一个时,名称不会显示,并且出现以下错误:

MUI: The value provided to Autocomplete is invalid.None of the options match with `1`.You can use the `isOptionEqualToValue` prop to customize the equality test. 
Run Code Online (Sandbox Code Playgroud)

Lin*_*ste 7

1. 扁平化列表

我的方法是将类别列表“展平”为单个数组,以便 MUI 可以评估每个子类别。我的每个平面选项都有一个depth属性,以便我可以以正确的缩进级别显示它。

我们可以使用Checkboxes 示例中的代码并使用 MUI 属性添加缩进sx

renderOption={(props, option, { selected }) => (
  <li {...props}>
    <Checkbox checked={selected} sx={{ ml: 2 * option.depth }} />
    {option.name}
  </li>
)}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

2. 过滤匹配

我假设我们想要在仅与子类别术语匹配的子类别上方显示顶级类别。就像您链接的“ber”示例中一样,如果类别是“Fall Gold”,子类别是“Fall Gold Berry”。这意味着我们在决定一个术语是否匹配时应该考虑子术语。

为了实现这一目标,我matchTerms在所有选项对象上包含一个属性,并filterOptionsAutocomplete查看该属性的对象上使用自定义函数。使用该createFilterOptions实用程序,我们只需要确定要检查哪些文本:

filterOptions={(createFilterOptions({
  // join with some arbitrary separator to prevent matches across adjacent terms
  stringify: (option) => option.matchTerms.join("//")
}))}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

3. 突出显示

最后一部分是突出显示,它不包含在 MUI 中。MUI 文档推荐了该autosuggest-highlight包并包含如何使用它的示例。我们可以复制它,更改option.titleoption.name. 在此输入图像描述

完整代码

JavaScript

renderOption={(props, option, { selected }) => (
  <li {...props}>
    <Checkbox checked={selected} sx={{ ml: 2 * option.depth }} />
    {option.name}
  </li>
)}
Run Code Online (Sandbox Code Playgroud)

打字稿

filterOptions={(createFilterOptions({
  // join with some arbitrary separator to prevent matches across adjacent terms
  stringify: (option) => option.matchTerms.join("//")
}))}
Run Code Online (Sandbox Code Playgroud)

代码沙盒链接