如何解决如何仅显示数据列表中的文本而不显示值? 选项 1:使用 <select>选项 2:将 <input> 与 <datalist> 结合使用
假设我们有以下数据列表和一个 js 变量 var carID = ''
:
<input list="options" @change='${carID = e.target.value}'>
<datalist id="options">
<option value="ID_1">Ferrari</option>
<option value="ID_2">Lamborghini</option>
<option value="ID_3">Jeep</option>
</datalist>
我只想在我的选项中显示汽车名称,而不是选项值(即汽车的 ID),并将所选汽车的 ID(所选选项的值)存储在变量,而不是汽车名称。
我尝试了不同的解决方案,我发布了其中的 2 个(一个完全错误,一个正确但不完整,我在其他堆栈溢出问题中找到了这个):
- 错误:它根本不起作用,e.target.carID 是 ''。
<input list="options" @change="${carID = e.target.carID}">
<datalist id="options">
<option carID="ID_1" value="Ferrari"></option>
<option carID="ID_2" value="Lamborghini"></option>
<option carID="ID_3" value="Jeep"></option>
</datalist>
-
好的,它可以工作,但是如果我有两辆具有相同名称和不同 ID 的汽车怎么办?是的,第二辆车会被忽略,如果我选择第二辆车,我会存储第一辆车的 ID。
<input id='inputID' list="options" @change='${this.getValue}'> <datalist id="options"> <option data-value="ID_1" value="Ferrari"></option> <option data-value="ID_2" value="Lamborghini"></option> <option data-value="ID_3" value="Jeep"></option> <option data-value="ID_4" value="Jeep"></option> </datalist>
js:
getValue(){
let shownValue = this.shadowRoot.getElementById('inputID').value;
let rightValue =
this.shadowRoot.querySelector("#options[value='"+shownValue+"']").dataset.value;
carID = rightValue;
}
我不能使用 JQuery。你有什么解决办法?谢谢!
解决方法
您的代码 @change='${carID = e.target.carID}'
无法工作,因为 event handler binding 的右侧不可调用。您需要将其包装在匿名函数中,例如像这样:@change=${(e) => { this.carID = e.target.value }}
话虽如此,这就是我理解你想要做的:
- 有一个列表,用户可以从中选择。
- 在列表中,只显示汽车名称,不显示 ID。
- 将所选汽车的 ID 存储在
carID
中,而不是名称中。
我认为有两种方法可以做到这一点。
选项 1:使用 <select>
如果汽车列表是固定的,我认为最好使用 <select height="1">
元素为您服务,从而产生一个下拉框。包括小事件处理程序,它看起来像这样:
<select @change=${(e) => { this.carID = e.target.value }}>
<option value="ID_1">Ferrari</option>
<option value="ID_2">Lamborghini</option>
<option value="ID_3">Jeep</option>
<option value="ID_4">Jeep</option>
</select>
这将显示来自 <option>
元素的文本内容的文本,但从 value
的 <select>
设置 <option>
的 value
属性,并且凭借 onchange 事件处理程序将在元素上设置 carID
字段。
您甚至可以拥有两辆 ID 不同但名称相同的汽车。但是请注意,如果显示文本相同,您的用户将不知道要选择两个“Jeep”条目中的哪一个。所以这可能不是一个好主意(但我不知道你的完整用例)。
选项 2:将 <input>
与 <datalist>
结合使用
现在,如果汽车列表不是固定的,即允许用户输入任意数据并且选择列表不是为了限制他们的选择,而是为了帮助他们(防止错别字,加速输入)你可以使用具有关联 <input>
的 <datalist>
。但弹出窗口将同时显示 <option>
的值和文本内容(如果它们都已定义且不同)。如果您坚持只显示汽车的名称,而不是 ID,那么名称必须放在 value
(或文本内容)的 <option>
属性中。虽然您可以将 ID 放入数据集中,但实际上没有必要这样做。
在任何情况下,您都需要通过您自己的代码将值字符串映射回 ID。这仅在“汽车和名称”是一对一(又名双射)映射时才有效,因此不允许有两辆具有完全相同名称的汽车。 (否则您的代码无法仅通过查看名称就知道选择了哪个。)
const CARS_BY_ID = {
ID_1: 'Ferrari',ID_2: 'Lamborghini',ID_3: 'Jeep',}
class MyElem extends LitElement {
constructor() {
super();
this.carID = null;
}
render() {
return html`
<input list="myopts" @change=${this.carChanged}>
<datalist id="myopts">
${Object.values(CARS_BY_ID).map((name) => html`<option>${name}</option>`)}
</datalist>`;
}
carChanged(e) {
const name = e.target.value;
this.carID = null;
for (const [key,value] of Object.entries(CARS_BY_ID)) {
if (value === name) {
this.carID = key;
}
}
console.log(`this.carID = ${this.carID}`);
}
}
请注意,在此示例中,用户可以例如输入“Bugatti”,this.carID
将是 null
。
另请注意,this.carID
尚未注册为 lit-element 属性(未在 static get properties
中列出),因此不会触发更新生命周期,也不会发生重新渲染那个变化。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。