Angular adds strange options into select element when setting model value

允我心安 提交于 2019-11-27 01:55:21
lucuma

Angular does not set the value of a select element to the actual values of your array and does some internal things to manage the scope binding. See Mark Rajcok's first comment at this link:

https://docs.angularjs.org/api/ng/directive/select#overview

When the the user selects one of the options, Angular uses the index (or key) to lookup the value in array (or object) -- that looked-up value is what the model is set to. (So, the model is not set to the value you see in the HTML! This causes a lot of confusion.)

I'm not entirely sure using an ng-repeat is the best option.

Using the following syntax with ng-options solved this problem for me:

<select name="country_id" id="country_id" required="required" ng-model="newAddressForm.country_id" ng-options="country.id as country.name for country in countries">
  <option value="">Select Country</option>
</select>

If your values are integers you should use "" even if they're not strings, that simple reason is exactly why you're getting an option with a question mark as a value.

You shouldn't be using this:

{ value: 0, name: "Pendiente" },
{ value: 1, name: "Em andamento" },
{ value: 2, name: "Erro" },
{ value: 3, name: "Enviar email" },
{ value: 4, name: "Enviado" }

This is the right way:

{ value: "0", name: "Pendiente" },
{ value: "1", name: "Em andamento" },
{ value: "2", name: "Erro" },
{ value: "3", name: "Enviar email" },
{ value: "4", name: "Enviado" }

If you've at least one record which isn't using "" you'll be getting this ? option value.

I was running into this same problem earlier this evening, where I saw a select option showing up as the first in my list even though I didn't explicitly create it. I was filling a list of select options in my controller and using the same ng-options syntax mentioned above by jessedvrs (except that I was also inserting the "select an option" default option in the controller rather than marking it in the HTML like he was).

For some reason the select list would always show an additional option at index zero with a value of "?", but when I changed how I filled my default option in the controller, this issue went away. I was populating the select options by making an API call, filling them inside of a promise. I made the mistake of also populating my default "select an option" option as the first thing I did in that promise, but when I did this instead outside of the promise (prior to making the API call), the select options populated the way I waned them to.

I think jessedvrs option is one solution to the problem (setting the default option in the HTML markup), but if you prefer to populate your options in javascript instead, I would suggest to still set the default option prior to making any calls to an API or processes that may still be running while the HTML is being rendered.

When you assign a value to some select element, AngularJS looks for the provided value in the value attribute of the option tags in that select element. But the catch is, AngularJS does a type based comparison. So if the values in the option tags are strings (which usually is the case) and the variable you bind using ng-model is a number, AngularJS fails to find the matching option element and hence, creates its own element like this -

<option value="? integer:10 ?"></option>

The solution is, while binding itself, convert it to the appropriate type.

In this case, the solution would be to bind an Integer

<select name="country_id" id="country_id" required="required" ng-model="parseInt(newAddressForm.country_id)">
<option value="">Select Country</option>
<option ng-repeat="country in countries" value="{{country.id}}">{{country.name}}</option>
</select>

If the values are set as Strings, the trick would be to use

<select ... ng-model="newAddressForm.country_id.toString()" >
Manoj Atakare

While pushing data on scope variable we can use following code

$scope.enquiryLocationRow.push({'location': EnqLocation.location, 'state_id': Number(EnqLocation.state_id), 'country_id': Number(EnqLocation.country_id)});

it resolved my issue

use " track by 'value' " at the end of your ng-options :D

like the example below:

ng-options="country.id as country.name for country in countries track by country.id"

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!