<!DOCTYPE html>
<html>
<head>
<link data-require="bootstrap@*" data-semver="3.2.0" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.css" />
<script data-require="jquery@*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script data-require="bootstrap@*" data-semver="3.2.0" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.js"></script>
<script data-require="angular.js@*" data-semver="1.4.0-beta.0" src="https://code.angularjs.org/1.4.0-beta.0/angular.js"></script>
<script data-require="underscore.js@*" data-semver="1.6.0" src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="optionsApp">
<h1>Angular ng-Options by Example</h1>
<p>I use ngOptions infrequently enough that I don't remember how the comprehension expression
works, but often enough that hunting down appropriate examples is a nuisance. So I've compiled
a set of working examples here. I don't have 'track by' examples because they're for performance
and/or UI issues around refreshing data sources. Seems like a lot to accomplish here, and they
should be easy enough to 'tack on' as needed.
</p>
<div style="white-space: pre; font-family: monospace">
$scope.a = ['foo', 'bar', 'baz'];
$scope.pojo = {
pb: {id: 7, type: 'Spread', name: 'Peanut Butter'},
yellow: {id: 4, type: 'Condiment', name: 'Mustard'},
j: {id: 3, type: 'Spread', name: 'Jelly'},
jam: {id: 2, type: 'Spread', name: 'Jam'},
minty: {id: 1, type: 'Condiment', name: 'Mint Jelly'}
};
$scope.ao = [
{id: 7, type: 'Spread', name: 'Peanut Butter'},
{id: 4, type: 'Condiment', name: 'Mustard'},
{id: 3, type: 'Spread', name: 'Jelly'},
{id: 2, type: 'Spread', name: 'Jam'},
{id: 1, type: 'Condiment', name: 'Mint Jelly'}
];
$scope.range = _.range(6, 12);
</div>
<table ng-controller="optionsCtrl" class="table table-bordered">
<tbody>
<tr>
<th colspan="4">array data sources</th>
</tr>
<tr>
<th>form</th>
<th>actual</th>
<th>result</th>
<th>value</th>
</tr>
<tr>
<td>label for value in array</td>
<td>thing for thing in a</td>
<td>
<select ng-model="avalue1" ng-options="thing for thing in a"></select>
</td>
<td>{{ avalue1 }}</td>
</tr>
<tr>
<td></td>
<td>option|uppercase for option in a</td>
<td>
<select ng-model="ovalue" ng-options="option|uppercase for option in a"></select>
</td>
<td>{{ ovalue }}</td>
</tr>
<tr>
<td></td>
<td>number for number in range</td>
<td>
<select ng-model="rangevalue" ng-options="number for number in range"></select>
</td>
<td>{{ rangevalue }}</td>
</tr>
<tr>
<td></td>
<td>option.name for option in ao</td>
<td>
<select ng-model="aovalue1" ng-options="option.name for option in ao"></select>
</td>
<td>{{ aovalue1 }}</td>
</tr>
<tr>
<td>select as label for value in array</td>
<td>option.id as option.name for option in ao</td>
<td>
<select ng-model="aovalue2" ng-options="option.id as option.name for option in ao"></select>
</td>
<td>{{ aovalue2 }}</td>
</tr>
<tr>
<td>label group by group for value in array</td>
<td>option.name group by option.type for option in ao</td>
<td>
<select ng-model="aovalue3" ng-options="option.name group by option.type for option in ao"></select>
</td>
<td>{{ aovalue3 }}</td>
</tr>
<tr>
<td>select as label group by group for value in array</td>
<td>option.id as option.name group by option.type for option in ao</td>
<td>
<select ng-model="aovalue4" ng-options="option.id as option.name group by option.type for option in ao"></select>
</td>
<td>{{ aovalue4 }}</td>
</tr>
<tr>
<th colspan="4">object data sources</th>
</tr>
<tr>
<td>label for value in object</td>
<td>item.name for item in pojo</td>
<td>
<select ng-model="o1" ng-options="item.name for item in pojo"></select>
</td>
<td>{{ o1 }}</td>
</tr>
<tr>
<td>label for (key , value) in object</td>
<td>key for (key, item) in pojo</td>
<td>
<select ng-model="o2" ng-options="key for (key, item) in pojo"></select>
</td>
<td>{{ o2 }}</td>
</tr>
<tr>
<td>select as label for (key , value) in object</td>
<td>key as spread.name for (key, spread) in pojo</td>
<td>
<select ng-model="o3" ng-options="key as spread.name for (key, spread) in pojo"></select>
</td>
<td>{{ o3 }}</td>
</tr>
<tr>
<td>label group by group for (key, value) in object</td>
<td>id group by item.type for (id, item) in pojo</td>
<td>
<select ng-model="o4" ng-options="id group by item.type for (id, item) in pojo"></select>
</td>
<td>{{ o4 }}</td>
</tr>
<tr>
<td>select as label group by group for (key, value) in object</td>
<td>code as item.name group by item.type for (code, item) in pojo</td>
<td>
<select ng-model="o5" ng-options="code as item.name group by item.type for (code, item) in pojo"></select>
</td>
<td>{{ o5 }}</td>
</tr>
</tbody>
</table>
</body>
</html>
angular.module('optionsApp', [])
.controller('optionsCtrl', function ($scope) {
$scope.a = ['foo', 'bar', 'baz'];
$scope.pojo = {
pb: {id: 7, type: 'Spread', name: 'Peanut Butter'},
yellow: {id: 4, type: 'Condiment', name: 'Mustard'},
j: {id: 3, type: 'Spread', name: 'Jelly'},
jam: {id: 2, type: 'Spread', name: 'Jam'},
minty: {id: 1, type: 'Condiment', name: 'Mint Jelly'}
};
$scope.ao = [
{id: 7, type: 'Spread', name: 'Peanut Butter'},
{id: 4, type: 'Condiment', name: 'Mustard'},
{id: 3, type: 'Spread', name: 'Jelly'},
{id: 2, type: 'Spread', name: 'Jam'},
{id: 1, type: 'Condiment', name: 'Mint Jelly'}
];
$scope.range = _.range(6, 12);
$scope.pojo = {
spread: {
label: 'Spread',
values: [
{id: 7, name: 'Peanut Butter'},
{id: 3, name: 'Jelly'},
{id: 2, name: 'Jam'}
]
},
condiment: {
label: 'Condiment',
values: [
{id: 4, name: 'Mustard'},
{id: 1, name: 'Mint Jelly'}
]
}
};
});
/* Styles go here */
# Angular ng-Options by Example
I use ngOptions infrequently enough that I don't remember how the comprehension expression
works, but often enough that hunting down appropriate examples is a nuisance. So I've compiled
a set of working examples here. I don't have 'track by' examples because they're for performance
and/or UI issues around refreshing data sources. Seems like a lot to accomplish here, and they
should be easy enough to 'tack on' as needed.