问题
The Ember guide on binding data attributes says that "If you use data binding with a Boolean value, it will add or remove the specified attribute." I'm trying to use this feature to dynamically set the selected attributes on <option>s. I'm finding that I can dynamically set the disabled attribute, but the selected attribute is always omitted, no whether the boolean is true or false.
Given this handlebars template:
<option disabled={{false}} selected={{false}}>One</option>
<option disabled={{true}} selected={{true}}>Two</option>
I get the following HTML:
<option>One</option>
<option disabled>Two</option>
Why doesn't selected={{true}} produce a selected attribute in the rendered output?
To give a bit more context, I'm following this article on How to do a select in Ember 2.0. Using the method described in that article, I can successfully update the data in the controller when the select onchange event fires, but the DOM doesn't update to reflect the change.
I've put together this ember-twiddle, which includes two select elements. One uses select={{bool}}, which doesn't work the way I want it to. The other uses a long-hand {{#if bool}}...{{else}}...{{/if}}, which does work but looks terrible.
回答1:
Thanks to everyone who took the time to post an answer my question. Sonny's comment pointed me in the right direction:
selectedis a property, not an attribute with a value
This was news to me and it sent me down a rabbit-hole of discovery. I found this SO answer to be especially helpful.
When I posted the question, I didn't appreciate the difference between attributes and properties. I was expecting to see the selected attribute appear in the DOM, but this doesn't happen. I now understand that the selected property is being correctly set, and the fact that the <option> tag doesn't appear in the DOM with a selected attribute is of no consequence.
This code snippet helps to illustrate why I was confused. Both of the resulting <select> dropdown menus appear the same, with option 2 initially selected. The selected attribute does not appear in the DOM when it's set using selected={{true}}, but it does appear in the DOM in the other case:
<select>
<option>1</option>
<option selected={{true}}>2</option>
</select>
<select>
<option>1</option>
<option selected>2</option>
</select>
Here's the same snippet as a Twiddle
回答2:
You can use a helper which compares you option value to a reference somewhere like
<select onchange={{action "countryChanged" value="target.value"}}>
{{#each countries as |country|}}
<option value={{country.id}} selected={{is-equal country model.address.country_code}}>{{country.name}}</option>
{{/each}}
</select>
Inside your "Helpers" folder (create if not already there)
create your helper file like "is-equal.js"
import Ember from 'ember';
export default Ember.Helper.helper(function([lhs, rhs]) {
return lhs === rhs;
});
Which will just compare 2 values and return a boolean, you could also return a classname or whatever you like.
The action sets the user selected value to the model.address.country_code, the helper compares the new values, if the selected value matches the option value selected will get set to true.
回答3:
I was able to set the selected option using a variable as seen here: https://gist.github.com/fenichelar/d3cfa5c59783fdbf02d32bcc3b3a028d
Here is the Ember Twiddle: https://ember-twiddle.com/d3cfa5c59783fdbf02d32bcc3b3a028d?openFiles=templates.application.hbs%2C
Relevant Code:
application.js
import Ember from 'ember';
export default Ember.Controller.extend({
one: false,
two: true,
three: false
});
application.hbs
<div>
<select>
<option selected={{one}}>One</option>
<option selected={{two}}>Two</option>
<option selected={{three}}>Three</option>
</select>
</div>
来源:https://stackoverflow.com/questions/41839681/how-can-i-dynamically-set-the-selected-attribute-on-an-option-tag