@@ -66,9 +66,7 @@ var ngOptionsMinErr = minErr('ngOptions');
66
66
*
67
67
* ### `select` **`as`** and **`track by`**
68
68
*
69
- * <div class="alert alert-warning">
70
- * Be careful when using `select` **`as`** and **`track by`** in the same expression.
71
- * </div>
69
+ * When using `select` **`as`** and **`track by`** in the same expression use the `$value` variable.
72
70
*
73
71
* Given this array of items on the $scope:
74
72
*
@@ -110,6 +108,14 @@ var ngOptionsMinErr = minErr('ngOptions');
110
108
* expression evaluates to `items[0].subItem.id` (which is undefined). As a result, the model value
111
109
* is not matched against any `<option>` and the `<select>` appears as having no selected value.
112
110
*
111
+ * here is the fixed version of the broken example above.
112
+ *
113
+ * ```html
114
+ * <select ng-options="item.subItem as item.label for item in items track by $value.id" ng-model="selected"></select>
115
+ * ```
116
+ * ```js
117
+ * $scope.selected = $scope.items[0].subItem;
118
+ * ```
113
119
*
114
120
* @param {string } ngModel Assignable AngularJS expression to data-bind to.
115
121
* @param {comprehension_expression } ngOptions in one of the following forms:
@@ -285,7 +291,7 @@ var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile,
285
291
function ( value , locals ) { return trackByFn ( scope , locals ) ; } :
286
292
function getHashOfValue ( value ) { return hashKey ( value ) ; } ;
287
293
var getTrackByValue = function ( value , key ) {
288
- return getTrackByValueFn ( value , getLocals ( value , key ) ) ;
294
+ return getTrackByValueFn ( value , getLocals ( value , key , true ) ) ;
289
295
} ;
290
296
291
297
var displayFn = $parse ( match [ 2 ] || match [ 1 ] ) ;
@@ -294,12 +300,10 @@ var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile,
294
300
var valuesFn = $parse ( match [ 8 ] ) ;
295
301
296
302
var locals = { } ;
297
- var getLocals = keyName ? function ( value , key ) {
298
- locals [ keyName ] = key ;
299
- locals [ valueName ] = value ;
300
- return locals ;
301
- } : function ( value ) {
303
+ var getLocals = function ( value , key , isViewValue ) {
304
+ if ( keyName ) locals [ keyName ] = key ;
302
305
locals [ valueName ] = value ;
306
+ locals [ '$value' ] = isViewValue ? value : viewValueFn ( value , locals ) ;
303
307
return locals ;
304
308
} ;
305
309
@@ -345,7 +349,7 @@ var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile,
345
349
var key = ( optionValues === optionValuesKeys ) ? index : optionValuesKeys [ index ] ;
346
350
var value = optionValues [ key ] ;
347
351
348
- var locals = getLocals ( value , key ) ;
352
+ var locals = getLocals ( value , key , true ) ;
349
353
var selectValue = getTrackByValueFn ( value , locals ) ;
350
354
watchedArray . push ( selectValue ) ;
351
355
@@ -378,7 +382,7 @@ var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile,
378
382
for ( var index = 0 ; index < optionValuesLength ; index ++ ) {
379
383
var key = ( optionValues === optionValuesKeys ) ? index : optionValuesKeys [ index ] ;
380
384
var value = optionValues [ key ] ;
381
- var locals = getLocals ( value , key ) ;
385
+ var locals = getLocals ( value , key , false ) ;
382
386
var viewValue = viewValueFn ( scope , locals ) ;
383
387
var selectValue = getTrackByValueFn ( viewValue , locals ) ;
384
388
var label = displayFn ( scope , locals ) ;
0 commit comments