See ngOptions
ngOptions(optional) – {comprehension_expression=
} – in one of the
following forms:
For array data sources:
label for value in array
select as label for value in array
label group by group for value in array
select as label group by group for value in array track by trackexpr
For object data sources:
label for (key , value) in object
select as label for (key , value) in object
label group by group for (key, value) in object
select as label group by group for (key, value) in object
In your case, it should be
array = [{ "value": 1, "text": "1st" }, { "value": 2, "text": "2nd" }];
<select ng-options="obj.value as obj.text for obj in array"></select>
Update
With the updates on AngularJS, it is now possible to set the actual value for the value
attribute of select
element with track by
expression.
<select ng-options="obj.text for obj in array track by obj.value">
</select>
How to remember this ugly stuff
To all the people who are having hard time to remember this syntax form: I agree this isn't the most easiest or beautiful syntax. This syntax is kind of an extended version of Python's list comprehensions and knowing that helps me to remember the syntax very easily. It's something like this:
Python code:
my_list = [x**2 for x in [1, 2, 3, 4, 5]]
> [1, 4, 9, 16, 25]
# Let people to be a list of person instances
my_list2 = [person.name for person in people]
> my_list2 = ['Alice', 'Bob']
This is actually the same syntax as the first one listed above. However, in <select>
we usually need to differentiate between the actual value in code and the text shown (the label) in a <select>
element.
Like, we need person.id
in the code, but we don't want to show the id
to the user; we want to show its name. Likewise, we're not interested in the person.name
in the code. There comes the as
keyword to label stuff. So it becomes like this:
person.id as person.name for person in people
Or, instead of person.id
we could need the person
instance/reference itself. See below:
person as person.name for person in people
For JavaScript objects, the same method applies as well. Just remember that the items in the object is deconstructed with (key, value)
pairs.
Pick an element in the HTML panel of the developer tools and type this in the console:
angular.element($0).scope()
In WebKit and Firefox, $0
is a reference to the selected DOM node in the elements tab, so by doing this you get the selected DOM node scope printed out in the console.
You can also target the scope by element ID, like so:
angular.element(document.getElementById('yourElementId')).scope()
Addons/Extensions
There are some very useful Chrome extensions that you might want to check out:
Batarang. This has been around for a while.
ng-inspector. This is the newest one, and as the name suggests, it allows you to inspect your application's scopes.
Playing with jsFiddle
When working with jsfiddle you can open the fiddle in show mode by adding /show
at the end of the URL. When running like this you have access to the angular
global. You can try it here:
http://jsfiddle.net/jaimem/Yatbt/show
jQuery Lite
If you load jQuery before AngularJS, angular.element
can be passed a jQuery selector. So you could inspect the scope of a controller with
angular.element('[ng-controller=ctrl]').scope()
Of a button
angular.element('button:eq(1)').scope()
... and so on.
You might actually want to use a global function to make it easier:
window.SC = function(selector){
return angular.element(selector).scope();
};
Now you could do this
SC('button:eq(10)')
SC('button:eq(10)').row // -> value of scope.row
Check here: http://jsfiddle.net/jaimem/DvRaR/1/show/
Best Answer
The first time the listener is called, the old value and the new value will be identical. So just do this:
This is actually the way the Angular docs recommend handling it: