@@ -66,17 +66,13 @@ var ngOptionsMinErr = minErr('ngOptions');
66
66
* ### `select` **`as`** and **`track by`**
67
67
*
68
68
* <div class="alert alert-warning">
69
- * Do not use `select` **`as`** and **`track by`** in the same expression. They are not designed to work together .
69
+ * Be careful when using `select` **`as`** and **`track by`** in the same expression.
70
70
* </div>
71
71
*
72
- * Consider the following example:
73
- *
74
- * ```html
75
- * <select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected"></select>
76
- * ```
72
+ * Given this array of items on the $scope:
77
73
*
78
74
* ```js
79
- * $scope.values = [{
75
+ * $scope.items = [{
80
76
* id: 1,
81
77
* label: 'aLabel',
82
78
* subItem: { name: 'aSubItem' }
@@ -85,20 +81,33 @@ var ngOptionsMinErr = minErr('ngOptions');
85
81
* label: 'bLabel',
86
82
* subItem: { name: 'bSubItem' }
87
83
* }];
84
+ * ```
88
85
*
89
- * $scope.selected = { name: 'aSubItem' };
86
+ * This will work:
87
+ *
88
+ * ```html
89
+ * <select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
90
90
* ```
91
+ * ```js
92
+ * $scope.selected = $scope.items[0];
93
+ * ```
94
+ *
95
+ * but this will not work:
91
96
*
92
- * With the purpose of preserving the selection, the **`track by`** expression is always applied to the element
93
- * of the data source (to `item` in this example). To calculate whether an element is selected, we do the
94
- * following:
97
+ * ```html
98
+ * <select ng-options="item.subItem as item.label for item in items track by item.id" ng-model="selected"></select>
99
+ * ```
100
+ * ```js
101
+ * $scope.selected = $scope.items[0].subItem;
102
+ * ```
95
103
*
96
- * 1. Apply **`track by`** to the elements in the array. In the example: `[1, 2]`
97
- * 2. Apply **`track by`** to the already selected value in `ngModel`.
98
- * In the example: this is not possible as **`track by`** refers to `item.id`, but the selected
99
- * value from `ngModel` is `{name: 'aSubItem'}`, so the **`track by`** expression is applied to
100
- * a wrong object, the selected element can't be found, `<select>` is always reset to the "not
101
- * selected" option.
104
+ * In both examples, the **`track by`** expression is applied successfully to each `item` in the
105
+ * `items` array. Because the selected option has been set programmatically in the controller, the
106
+ * **`track by`** expression is also applied to the `ngModel` value. In the first example, the
107
+ * `ngModel` value is `items[0]` and the **`track by`** expression evaluates to `items[0].id` with
108
+ * no issue. In the second example, the `ngModel` value is `items[0].subItem` and the **`track by`**
109
+ * expression evaluates to `items[0].subItem.id` (which is undefined). As a result, the model value
110
+ * is not matched against any `<option>` and the `<select>` appears as having no selected value.
102
111
*
103
112
*
104
113
* @param {string } ngModel Assignable angular expression to data-bind to.
0 commit comments