使用 PreactJS 以编程方式填充“<select>”元素
Programmatically populating a `<select>` element, using PreactJS
class MySelect extends Component {
constructor(params, renderFunction, uniqueId) {
super(params);
this.params = {
...params,
};
this.uniqueId = uniqueId;
this.state = params.state; // not sure why I need this to avoid a null state?
this.updateColours = this.updateColours.bind(this);
// I also tried to "dangerously set innerHTML" with this:
// this.optionElems = '';
// Object.keys(this.params.options).forEach(key => {
// this.optionElems += `<option key="${key}" value="${key}">${this.params.options[key]}</option>`;
// });
}
...
render(params, state) {
const { options } = this.params;
return (
<div className='my-select'>
<select value='BAR' onChange={(event) => this.updateColours(event)} options={options} >
<option value='FOO'>Foo</option>
<option value='BAR'>Bar</option>
{Object.keys(options).forEach(key => {
return <option key={key} value={key}>{options[key]}</option>;
})}
</select>
</div>);
}
它在主应用程序中是这样调用的:
const myObj = {
ONE: 'First option',
TWO: 'Second option',
}
...
<MySelect wrapper={this.wrapper} state={this.state} options={myObj} />
渲染器时,我是否希望页面上的 select 包含:
<select>
<option value="FOO">Foo</option>
<option value="BAR">Bar</option>
<option value="ONE">First item</option>
<option value="TWO">Second item</option>
</select>
但我得到的只是:
<select>
<option value="FOO">Foo</option>
<option value="BAR">Bar</option>
</select>
注意:
我也试过这个(首先定义选项..):
render(params, state) {
const { options } = this.params;
const optionsItems = Object.keys(options).forEach(key => {
console.log('option: val, name', key, options[key]);
return <option key={key} value={key}>{options[key]}</option>;
});
console.log('options, optionsItems', options, optionsItems);
return (
<div className='my-select'>
<select value='BAR' onChange={(event) => this.updateColours(event)} options={options} >
{optionsItems}
</select>
</div>);
}
options
、params
、optionsItem
都不为空,都是我期望的log..
我看了很多东西都无济于事:
好的,我找到了解决方案..
我想对大多数人来说很明显:
您必须使用以下格式的对象数组:
在调用我的 <MySelect>
组件的脚本中,靠近顶部的某处;
const options = [
{ value: "ONE", name: 'First item' },
{ value: "TWO", name: 'Second item' },
];
然后在 MySelect
组件的渲染函数中:
render(params, state) {
const optionsItems = this.params.options.map((data) => <option key={data.value} value={data.value}>{data.name}</option>);
return (
<div className='my-select'>
<select onChange={(event) => this.updateColours(event)}>
{optionsItems}
</select>
</div>);
您也可以这样尝试,这实际上是一样的,但是如果您要渲染一个复杂的html,您可以试试这个
render(params, state) {
return (
<div className='my-select'>
<select value='BAR' onChange={(event) => this.updateColours(event)}>
{this.params.options.map((data) => <option key={data.id} value={data.id}>{data.name}</option>)}
</select>
</div>);
我发现不使渲染函数复杂化会更整洁
class MySelect extends Component {
constructor(params, renderFunction, uniqueId) {
super(params);
this.params = {
...params,
};
this.uniqueId = uniqueId;
this.state = params.state; // not sure why I need this to avoid a null state?
this.updateColours = this.updateColours.bind(this);
// I also tried to "dangerously set innerHTML" with this:
// this.optionElems = '';
// Object.keys(this.params.options).forEach(key => {
// this.optionElems += `<option key="${key}" value="${key}">${this.params.options[key]}</option>`;
// });
}
...
render(params, state) {
const { options } = this.params;
return (
<div className='my-select'>
<select value='BAR' onChange={(event) => this.updateColours(event)} options={options} >
<option value='FOO'>Foo</option>
<option value='BAR'>Bar</option>
{Object.keys(options).forEach(key => {
return <option key={key} value={key}>{options[key]}</option>;
})}
</select>
</div>);
}
它在主应用程序中是这样调用的:
const myObj = {
ONE: 'First option',
TWO: 'Second option',
}
...
<MySelect wrapper={this.wrapper} state={this.state} options={myObj} />
渲染器时,我是否希望页面上的 select 包含:
<select>
<option value="FOO">Foo</option>
<option value="BAR">Bar</option>
<option value="ONE">First item</option>
<option value="TWO">Second item</option>
</select>
但我得到的只是:
<select>
<option value="FOO">Foo</option>
<option value="BAR">Bar</option>
</select>
注意:
我也试过这个(首先定义选项..):
render(params, state) {
const { options } = this.params;
const optionsItems = Object.keys(options).forEach(key => {
console.log('option: val, name', key, options[key]);
return <option key={key} value={key}>{options[key]}</option>;
});
console.log('options, optionsItems', options, optionsItems);
return (
<div className='my-select'>
<select value='BAR' onChange={(event) => this.updateColours(event)} options={options} >
{optionsItems}
</select>
</div>);
}
options
、params
、optionsItem
都不为空,都是我期望的log..
我看了很多东西都无济于事:
好的,我找到了解决方案..
我想对大多数人来说很明显:
您必须使用以下格式的对象数组:
在调用我的 <MySelect>
组件的脚本中,靠近顶部的某处;
const options = [
{ value: "ONE", name: 'First item' },
{ value: "TWO", name: 'Second item' },
];
然后在 MySelect
组件的渲染函数中:
render(params, state) {
const optionsItems = this.params.options.map((data) => <option key={data.value} value={data.value}>{data.name}</option>);
return (
<div className='my-select'>
<select onChange={(event) => this.updateColours(event)}>
{optionsItems}
</select>
</div>);
您也可以这样尝试,这实际上是一样的,但是如果您要渲染一个复杂的html,您可以试试这个
render(params, state) {
return (
<div className='my-select'>
<select value='BAR' onChange={(event) => this.updateColours(event)}>
{this.params.options.map((data) => <option key={data.id} value={data.id}>{data.name}</option>)}
</select>
</div>);
我发现不使渲染函数复杂化会更整洁