Ember.js+Handlebars中select的option选中属性设置失效问题
我之前也碰到过一模一样的问题,其实这不是你代码写错了,而是Ember对表单元素的状态处理逻辑和你想的不一样!
问题根源:Ember的表单数据驱动理念
Ember会通过绑定<select>元素的value属性来统一控制选中状态,而不是让你手动给单个<option>设置selected属性。这是因为Ember遵循数据驱动的设计——表单控件的状态应该由组件的数据源(比如组件属性)来决定,而不是直接操作DOM属性。
你之前尝试的selected={{if (is-item-selected item.state) "selected"}}之所以无效,是因为Ember会自动接管<select>的选中状态,你的手动设置会被它的绑定逻辑覆盖。而data-selected这类自定义data-*属性不属于表单原生状态属性,所以不会被Ember干预,自然能正常显示。
正确的解决方案:用value绑定控制选中状态
你需要把选中状态的控制权交给<select>的value绑定,而不是逐个操作option的属性,具体步骤如下:
1. 在组件JS里定义选中值的计算属性
先找到当前应该被选中的item的value,把它作为组件的属性:
import Component from '@ember/component'; import { computed } from '@ember/object'; export default Component.extend({ // 根据items的state计算当前选中的value selectedValue: computed('items.@each.state', function() { const selectedItem = this.items.find(item => item.state === 2); // 如果没有选中项,返回空字符串对应默认的placeholder选项 return selectedItem ? selectedItem.value : ''; }), // 你的其他组件逻辑,比如itemClicked动作 actions: { itemClicked(selectedValue) { // 这里可以更新选中状态到数据源,比如修改对应item的state this.items.forEach(item => { item.state = item.value === selectedValue ? 2 : 0; }); } } });
2. 修改模板中的select标签
去掉option上的selected属性,给<select>绑定value={{selectedValue}}:
<select aria-disabled="{{disabled}}" aria-multiselectable="{{multiselect}}" disabled={{cannotOpen}} value={{selectedValue}} onchange={{action 'itemClicked' value='target.value'}} > <option disabled value="">{{placeholder}}</option> {{#each items as |item|}} <option value={{item.value}} disabled={{item.disabled}}> {{item.name}} </option> {{/each}} </select>
多选场景的补充(如果需要)
如果你用的是多选下拉(aria-multiselectable="true"),只需要额外添加multiple=true,并把value绑定到一个数组属性即可:
<select multiple=true value={{selectedValues}} <!-- selectedValues是组件中的数组属性 --> <!-- 其他属性不变 --> > <!-- option部分不变 --> </select>
这样修改后,Ember会根据selectedValue自动匹配对应的option并设置选中状态,完全符合它的数据驱动逻辑,问题就解决啦!
内容的提问来源于stack exchange,提问作者Kameron Kincade

