【发布时间】:2017-07-24 19:49:30
【问题描述】:
有人知道如何为自动完成组件添加默认值吗?
该组件有一个dataSource,我想加载已经选择了特定项目的页面(例如,用所选项目的文本填充文本字段,并且它的值已经设置)。 p>
有人知道怎么做吗?非常感谢您的帮助
【问题讨论】:
标签: material-ui
有人知道如何为自动完成组件添加默认值吗?
该组件有一个dataSource,我想加载已经选择了特定项目的页面(例如,用所选项目的文本填充文本字段,并且它的值已经设置)。 p>
有人知道怎么做吗?非常感谢您的帮助
【问题讨论】:
标签: material-ui
如果您与过滤器选项一起使用会在每个过滤器上加载 API,这特别棘手。我可以通过在 state 和 onInputChange 选项中设置来加载初始值。
以下是适用于我的代码,或单击下面的链接查看完整的工作演示。
https://codesandbox.io/s/smoosh-brook-xgpkq?fontsize=14&hidenavigation=1&theme=dark
import React, { useState, useEffect } from "react";
import TextField from "@material-ui/core/TextField";
import Typography from "@material-ui/core/Typography";
import Autocomplete from "@material-ui/lab/Autocomplete";
export default function CreateEditStrategy({ match }) {
const [user, setUser] = useState({
_id: "32778",
name: "Magic User's Club!"
});
const [filter, setFilter] = useState("");
const [users, setUsers] = useState([]);
const [openAutoComplete, setOpenAutoComplete] = React.useState(false);
useEffect(() => {
(async () => {
//Will not filter anything for testing purpose
const response = await fetch(
`https://api.tvmaze.com/search/shows?q=${filter}`
);
const shows = await response.json();
setUsers(
shows.map((a, i) => {
return { _id: a.show.id, name: a.show.name };
})
);
})();
}, [filter]);
return (
<div>
<Typography variant="h6">Autocomplete</Typography>
<Autocomplete
open={openAutoComplete}
onOpen={() => setOpenAutoComplete(true)}
value={user}
inputValue={filter}
onClose={() => setOpenAutoComplete(false)}
onChange={(event, user) => {
if (user) setUser(user);
else setUser({ _id: "", name: "" });
}}
onInputChange={(event, newInputValue) => setFilter(newInputValue)}
getOptionSelected={(option, value) => option.name === value.name}
getOptionLabel={(option) => option.name}
options={users}
renderInput={(params) => (
<TextField
{...params}
label="Asynchronous"
variant="outlined"
InputProps={{
...params.InputProps
}}
/>
)}
/>
</div>
);
}
【讨论】:
您可以为 AutoComplete 提供 defaultValue 属性。
<Autocomplete
multiple
id="tags-outlined"
options={
this.state.categories
}
getOptionLabel={(option) => option.category_name
}
onChange={this.handleAutocomplete}
defaultValue={'yourDefaultStringValue'} // put your default value here
filterSelectedOptions
renderInput={(params) => (
<TextField
fullWidth
{...params}
variant="outlined"
label="Add Categories"
placeholder="Category"
required
/>
【讨论】:
这种方法对我有用(使用钩子):
首先在一个变量中定义你需要的选项:
const genderOptions = [{ label: 'M' }, { label: 'V' }];
其次,您可以定义一个挂钩来存储所选值(例如将其存储在会话存储中以供页面刷新时使用,或直接使用 useState):
const age = useSessionStorage('age', '');
接下来,您可以按如下方式定义您的自动完成功能(注意 value 和 getOptionLabel 中的默认值,如果您省略这些,您将获得那些受控到不受控的警告):
<Autocomplete
id="id"
options={ageOptions}
getOptionLabel={option => option.label || ""}
value={ageOptions.find(v => v.label === age[0]) || {}} // since we have objects in our options array, this needs to be a object as well
onInputChange={(_, v) => age[1](v)}
renderInput={params => (
<TextField {...params} label="Leeftijd" variant="outlined" />
)}
/>
【讨论】:
我尝试了上述所有解决方案,但没有任何效果。从那时起,API 可能发生了变化。
我终于想出了一个解决办法。它不是那么优雅,但原则上它是有道理的。在我的情况下,选项是对象。我只需要使用选项数组中的确切项目设置“值”道具。这样就不需要 componentDidMount 和 getOptionSelected。
在我们的例子中,自动完成被包裹在另一个组件中。这是主要代码:
class CTAutoComplete extends React.PureComponent {
getSelectedItem(){
const item = this.props.options.find((opt)=>{
if (opt.value == this.props.selectedValue)
return opt;
})
return item || {};
}
render() {
return (
<Autocomplete
id={this.props.id}
className={this.props.className}
style={{ width: '100%' }}
options={this.props.options}
getOptionLabel={this.props.getOptionLabel}
renderInput={params => (
<TextField {...params} label={this.props.label} variant="outlined" />
)}
onChange={this.props.onChange}
value={this.getSelectedItem()}
/>
);
}
}
重要提示:设置“value”时,您必须确保输入 null 大小写“|| {}”,否则 React 会抱怨您正在从不受控制的组件更改为受控组件。
【讨论】:
onUpdateInput 为我工作 - 对于任何像我一样浏览这一切的人
【讨论】:
onUpdateInput 属性。 material-ui.com/api/autocomplete
您可以通过在componentDidMount中设置适当的状态来实现这一点,例如:
componentDidMount() {
// load your items into your autocomplete
// set your default selected item
this.setState({ allItems: [itemYouWantToSet], selectedItem: item.name, selectedItemId: item.id }
}
render() {
return (
<Autocomplete
value={this.state.selectedItem}
items={this.state.allItems}
getItemValue={(item) => item.name}
onSelect={(value, item) => {
this.setState({ selectedItem: value, selectedItemId: value, allItems: [item] });
}}
/>
)
}
然后您的项目在加载时从可用选项列表中正确选择。
【讨论】:
value={obj} 属性中的对象。
getItemValue 属性。”
像这样调用你的组件
<SelectCountryAutosuggest searchText="My Default Value" />
确保在类加载时应用默认值
class SelectCountryAutosuggest extends React.Component {
state = {
value: this.props.searchText, //apply default value instead of ''
suggestions: [],
};
...
}
【讨论】:
试试这个...
componentWillReceiveProps(nextProps) {
let value = nextProps.value
if (value) {
this.setState({
value: value
})
}
}
【讨论】:
您是否尝试过动态设置 searchText 属性?您可以将要设置的值作为 searchText 属性传递给自动完成组件。类似的,
<Autocomplete
searchText={this.state.input.name} // usually value={this.state.input.name}
/>
默认情况下,它会在Autocomplete 组件的TextField 中设置初始值,但是当用户进行任何修改时,它会根据dataSource 属性调用自动完成选项。
【讨论】:
您可以使用searchText 属性。
<AutoComplete searchText="example" ... />
【讨论】:
TextField 中的文本。仅设置searchText 的问题是您必须循环所有dataSource 才能找到与文本匹配的值。在我的情况下,我正在使用来自已经具有该值的服务器的数据加载表单,但我需要填充它的 TextField 并设置它的值以防用户不更改字段所以它的字段准备发送。