我有一个自动完成 MUI 组件,并且我仍在学习它的一些功能。我的基本实现按预期工作,这意味着使用以下代码:
import Autocomplete from '@mui/material/Autocomplete';
import { TextField } from '@mui/material';
import * as React from 'react';
const options = [
{
"value": {"name": "Bill Simmons HR"},
"label": "BILL SIMMONS HR"
},
]
const label = "Field"
export function MyAutocomplete() {
return (
<label>
<Autocomplete
sx={{width: 200}}
options={options}
id="custom-input-demo"
renderInput={(params) => (
<TextField
{...params}
label={label}
placeholder={label}
/>
)}
/>
</label>
);
}
...如果我输入其中任何一个,它会按预期工作并且自动完成选项可见:
"bill"
"bill "
"bill s"
"bill simmons"
"bill simmons hr"
"simmons"
"simmons "
我的问题是,我有一个要求 - 除了上述功能之外 - 应该通过键入以下任何输入来显示自动完成可见选项,因此我也需要这些功能:
"simmons b"
"simmons bill"
通过我的基本实现,上面的两个输入会导致任何自动完成选项消失。
MUI 文档建议,要更改默认选项过滤器行为,我应该使用
createFilterOptions
工厂创建自定义过滤器。所以,我做到了:
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
import { TextField } from '@mui/material';
import * as React from 'react';
const options = [
{
"value": {"name": "Bill Simmons HR"},
"label": "BILL SIMMONS HR"
},
]
const SPACE = " "
function parse(label:string) {
const arr = label.split(SPACE)
return arr[1] + SPACE + arr[0] + SPACE + arr[2] // <<<--- enables new requirement, but disables original functionality
}
const filterOptions = createFilterOptions({
matchFrom: 'start',
stringify: (option:any) => parse(option.label),
})
const label = "Field"
export function MyAutocomplete() {
return (
<label>
<Autocomplete
filterOptions={filterOptions}
sx={{width: 200}}
options={options}
id="custom-input-demo"
renderInput={(params) => (
<TextField
{...params}
label={label}
placeholder={label}
/>
)}
/>
</label>
);
}
现在这个自定义过滤器满足了新的要求,但它禁用了原来的功能。
我该怎么做才能满足以下所有输入都显示自动完成选项的两种用例?
"bill"
"bill "
"bill s"
"bill simmons"
"bill simmons hr"
"simmons"
"simmons "
"simmons b"
"simmons bill"
反应:v18,muiv:5
听起来你想要的是模糊搜索,这样无论词序如何,你都可以看到你想要的东西。
我尝试了一下,并使用了文档“高级”部分中的示例,以及“高级”部分中链接的示例代码,并且能够实现您所要求的 --
const filterOptions = (options, { inputValue }) => {
const optionsForSearch = options.map((o) => o.label)
const terms = inputValue.split(' ')
const result = terms.reduceRight(
(accu, term) => matchSorter(accu, term),
optionsForSearch
)
Ï
return result
}
简而言之,
createFilterOptions
将无法实现您所要求的仅仅是因为它的限制(同时仍然非常足智多谋)。因此,您需要一个更加自定义的过滤器才能使模糊搜索正常工作。
这里是演示,其中包含部分代码和部分代码片段,灵感来自 MUI 的文档 - https://codesandbox.io/s/cool-river-f2m8gt?file=/src/Demo.tsx:333 -602