Do you want to request a _feature_ or report a _bug_?
Bug.
What is the current behavior?
In 1.5.6 an html <option>
with ngSelected seems to have the selected
attribute applied, but that option won't highlight. Tried with Chrome.
This happen when using ngSelected in combination with ngRepeat; if used in static <option>
elements it works fine.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (template: http://plnkr.co/edit/tpl:yBpEi4).
Example code:
<select ng-model="user.item_id">
<option ng-selected="i.id == user.item_id" ng-repeat="i in items" value={{i.id}}>
{{i.name}}
</option>
</select>
Plunker: https://plnkr.co/edit/7oi4KwzMhGi3kdltSklg?p=preview
What is the expected behavior?
The option should actually get highlighted - like it worked until 1.3.20
Plunker to the working version: https://plnkr.co/edit/0ApQeZ6Kar2yQisELXfT?p=preview
What is the motivation / use case for changing the behavior?
n\a
Which versions of Angular, and which browser / OS are affected by this issue? Did this work in previous versions of Angular? Please also test with the latest stable and snapshot (https://code.angularjs.org/snapshot/) versions.
Chrome 51.0.2704.103 m
Win 7 Ultimate 64 bit
Other information (e.g. stacktraces, related issues, suggestions how to fix)
n\a
What happens if you use ngSelected and ngModel together was never really specified. It looks like at some point ngModel took priority over ngSelected - as I would expect it to happen, as ngModel is the primary mechanism to bind a model to an input. Basically, when you are using ngSelected, you are trying to override the ngModel behavior. ngSelected should only be used if you don't use ngModel.
As you may have noticed, simply removing ngSelected won't work though. This is because your model is an integer, but your option values are strings (because attribute values are strings). You can see this also when you select an option - the id in your model will become a string instead of a integer.
In 1.6, it'll be possible to bind arbitrary values to an option with ngValue.
For now, you should use ngOptions:
https://plnkr.co/edit/3SoGVxbLw3lyjPSirVqt?p=preview
Or convert your ids to strings on the fly, see https://code.angularjs.org/snapshot/docs/api/ng/directive/select#binding-select-to-a-non-string-value-via-ngmodel-parsing-formatting
Thanks @Narretz.
I am still confused, i don't think this is related to a bad comparison.
Infact, if you inspect the rendered html code, you'll notice that the selected
attribute is applied to the right option. However, it won't highlight for some reason; that's why i didn't think that the problem was related to a bad comparison. Do you have any explanation to this?
I can't say exactly why ngSelected doesn't work anymore, other than it has to do with ngModel. I meant that ngModel won't be able to select your option in this case, because it compares string with integer. ngSelected will work without ngModel.
The logic for when a browser selects an option is also more complex than simply "respecting" the selected attribute.
So the issue is actually that we changed the select to compare === (strictly) instead of ==. In your working example plnkr, you can remove ngSelected, and the option is still selected.
So it doesn't work anymore because ngModel doesn't find the integer 1
, so it sets the select value to the unknown option ? number:1 ?
, and setting select value overwrites selected attributes on any options.
This definitely explain. Should we rely on a fix or should we stick to ngOptions? I think in the latter case the ngSelected docs should address this issue and provide more details.
I don't know why you say ngSelected
doesn't work. As documented, all ngSelected
does is set/unset the selected
attribute (not that you need it or that it matters when using ngModel
). It works fine in that regard.
Regarding your example, it doesn't work becaue of the strict comparison (1 !== '1'
) that @Narretz explained above. If you fix that, it works fine for me (tried on Chrome and Firefox): Updated plnkr
Did I miss something?
It's not only me saying that, @Narretz wrote
I can't say exactly why ngSelected doesn't work anymore
and
the issue is actually that we changed the select to compare === (strictly) instead of ==
That's a behaviour change introduced after 1.3.x that i've not seen documented.
It's not only me saying that, @Narretz wrote
I can't say exactly why ngSelected doesn't work anymore
I know. I am asking both of you :smile:
the issue is actually that we changed the select to compare === (strictly) instead of ==
That's a behaviour change introduced after 1.3.x that i've not seen documented.
This is mentioned in the select
docs and is documented as a breaking change both in the changelog (in the "Breaking Changes" section of the 1.4.0-beta.0 release) and in the Migration Guide (Migrating from 1.3 to 1.4).
(OOC, where did you look?)
I will close this, since everything works as expected (and is properly documented), but feel free to continue the discussion below.
This is mentioned in the select docs and is documented
My bad... missed that part.
Most helpful comment
What happens if you use ngSelected and ngModel together was never really specified. It looks like at some point ngModel took priority over ngSelected - as I would expect it to happen, as ngModel is the primary mechanism to bind a model to an input. Basically, when you are using ngSelected, you are trying to override the ngModel behavior. ngSelected should only be used if you don't use ngModel.
As you may have noticed, simply removing ngSelected won't work though. This is because your model is an integer, but your option values are strings (because attribute values are strings). You can see this also when you select an option - the id in your model will become a string instead of a integer.
In 1.6, it'll be possible to bind arbitrary values to an option with ngValue.
For now, you should use ngOptions:
https://plnkr.co/edit/3SoGVxbLw3lyjPSirVqt?p=preview
Or convert your ids to strings on the fly, see https://code.angularjs.org/snapshot/docs/api/ng/directive/select#binding-select-to-a-non-string-value-via-ngmodel-parsing-formatting