javascript - 如何将唯一分组用于 MUI 的自动完成组件?
我正在使用 MUI 的自动完成(Autocomplete)在搜索栏中对我的建议进行分组。我认为这看起来很简单,但其实不是。首先,请看看我的数据结构。
[{
"id" : 1,
"bookName" : "it starts with us",
"author" : "Colin Hoover"
},
{ "id" : 2,
"bookName" : "it ends with us",
"author" : "Colin Hoover"
},
{ "id" : 3,
"bookName" : "The great Gatsby",
"author" : "Scott Fitzgerald"
},
{ "id" : 4,
"bookName" : "To Kill a mocking bird",
"author" : "Harper Lee"
},
{ "id" : 5,
"bookName" : "Remainders of Him",
"author" : "Colin Hoover"
}, ... ]
现在你可以看到,有 3 本由 'Colin Hoover' 撰写的书,放置在不同的 ID 上。我想要实现的是,我的 MUI 自动完成组件应该渲染
Colin Hoover //author name as heading and books underneath it
Remainders of Him
It Ends with us
It starts with us
... other books from this specific author
到我的 MUI 的 Autocomplete 中的 groupBy 属性。
我现在遇到的问题 - 当我将某位作者的书籍按连续的 ID 排列(比如 id: 1, 2, 3, 4 ..)时,自动完成的分组功能工作正常(即,如果某位作者的书籍出现在连续的 ID 中,它会将这些不同的书籍分组到同一作者下)。但是,当我以随机顺序排列它们时(即 id 1, 3, 5, 8, 9 ..包含同名 "Colin Hoover" 的书籍),它就不会进行任何分组,而是会在自动建议列表中创建重复的标题 "Colin Hoover",这是我不希望发生的。
我只想在 MUI 的自动完成中显示相同的标题以及他/她以自己名义写的所有书籍。
这是我的代码
imports ...
export default function JobSearch () {
const [ books, setBooks ] = useState<Book[]>([]);
const [ searchTerm, setSearchTerm ] = useState<string>('');
// using redux
const dispatch = useAppDispatch();
const { status } = useAppSelector ( state => state.menu );
useEffect(() => {
agent.Books.getBooks() // my endpoint for getting the books
.then((books) => { setBooks(books);
console.log(books)})
.catch((error) => console.log(error))
}, []);
const suggestions = books.map((book) => {
const bookDetail = `${book.name} by ${book.author}`
return {
bookDetail,
...book
}});
const handleChangeInput = ( event : any ) => {
setSearchTerm( event.target.value);
console.log(event.target.value);
}
return (
<Fragment>
<Autocomplete
open = { status.name === "autoCompleteMenu" && status.open }
autoHighlight = {true}
autoComplete = {true}
noOptionsText = {`Search for ${searchTerm}`}
onOpen = { () => {
dispatch(setOpenMenu("autoCompleteMenu"));
}}
onClose = { () => dispatch(setCloseMenu("autoCompleteMenu"))}
options = {suggestions.sort((a, b) => -b.bookDetail.localeCompare(a.bookDetail))}
isOptionEqualToValue = {(option, value) => option.bookDetail === value.bookDetail}
groupBy = {(option) => option.author} // I want all books sorted under same author
getOptionLabel={(option) => option.bookDetail}
renderInput = {(params) => (
<TextField { ...params}
label = {'search ...'}
onChange = {handleChangeInput}
variant = {'outlined'} /> )} />
</Fragment>
)
}
我知道我必须在 groupBy 中实现 'sort',但如何做到同样的事情,以便根据作者姓名对所有书籍进行排序并将其作为 groupBy 属性的参数传递。
所有建议都欢迎并高度赞赏。