Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit d161cc6

Browse files
thorn0petebacondarwin
authored andcommitted
docs(select): improve formatting and wording
The part about using `select as` and `track by` together was hard to read. And it wasn't clear what happens if they're used together. Closes #10409
1 parent d604f94 commit d161cc6

File tree

1 file changed

+45
-21
lines changed

1 file changed

+45
-21
lines changed

src/ng/directive/select.js

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ var ngOptionsMinErr = minErr('ngOptions');
1313
*
1414
* The `ngOptions` attribute can be used to dynamically generate a list of `<option>`
1515
* elements for the `<select>` element using the array or object obtained by evaluating the
16-
* `ngOptions` comprehension_expression.
16+
* `ngOptions` comprehension expression.
1717
*
1818
* In many cases, `ngRepeat` can be used on `<option>` elements instead of `ngOptions` to achieve a
19-
* similar result. However, the `ngOptions` provides some benefits such as reducing memory and
19+
* similar result. However, `ngOptions` provides some benefits such as reducing memory and
2020
* increasing speed by not creating a new scope for each repeated instance, as well as providing
21-
* more flexibility in how the `select`'s model is assigned via `select as`. `ngOptions` should be
22-
* used when the `select` model needs to be bound to a non-string value. This is because an option
23-
* element can only be bound to string values at present.
21+
* more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the
22+
* comprehension expression. `ngOptions` should be used when the `<select>` model needs to be bound
23+
* to a non-string value. This is because an option element can only be bound to string values at
24+
* present.
2425
*
2526
* When an item in the `<select>` menu is selected, the array element or object property
2627
* represented by the selected option will be bound to the model identified by the `ngModel`
@@ -35,28 +36,51 @@ var ngOptionsMinErr = minErr('ngOptions');
3536
* array of objects. See an example [in this jsfiddle](http://jsfiddle.net/qWzTb/).
3637
* </div>
3738
*
38-
* ## `select as`
39+
* ## `select` **`as`**
3940
*
40-
* Using `select as` will bind the result of the `select as` expression to the model, but
41+
* Using `select` **`as`** will bind the result of the `select` expression to the model, but
4142
* the value of the `<select>` and `<option>` html elements will be either the index (for array data sources)
42-
* or property name (for object data sources) of the value within the collection. If a `track by` expression
43+
* or property name (for object data sources) of the value within the collection. If a **`track by`** expression
4344
* is used, the result of that expression will be set as the value of the `option` and `select` elements.
4445
*
45-
* ### `select as` with `track by`
4646
*
47-
* Using `select as` together with `track by` is not recommended. Reasoning:
47+
* ### `select` **`as`** and **`track by`**
48+
*
49+
* <div class="alert alert-warning">
50+
* Do not use `select` **`as`** and **`track by`** in the same expression. They are not designed to work together.
51+
* </div>
52+
*
53+
* Consider the following example:
54+
*
55+
* ```html
56+
* <select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected">
57+
* ```
58+
*
59+
* ```js
60+
* $scope.values = [{
61+
* id: 1,
62+
* label: 'aLabel',
63+
* subItem: { name: 'aSubItem' }
64+
* }, {
65+
* id: 2,
66+
* label: 'bLabel',
67+
* subItem: { name: 'bSubItem' }
68+
* }];
69+
*
70+
* $scope.selected = { name: 'aSubItem' };
71+
* ```
72+
*
73+
* With the purpose of preserving the selection, the **`track by`** expression is always applied to the element
74+
* of the data source (to `item` in this example). To calculate whether an element is selected, we do the
75+
* following:
76+
*
77+
* 1. Apply **`track by`** to the elements in the array. In the example: `[1, 2]`
78+
* 2. Apply **`track by`** to the already selected value in `ngModel`.
79+
* In the example: this is not possible as **`track by`** refers to `item.id`, but the selected
80+
* value from `ngModel` is `{name: 'aSubItem'}`, so the **`track by`** expression is applied to
81+
* a wrong object, the selected element can't be found, `<select>` is always reset to the "not
82+
* selected" option.
4883
*
49-
* - Example: &lt;select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected"&gt;
50-
* values: [{id: 1, label: 'aLabel', subItem: {name: 'aSubItem'}}, {id: 2, label: 'bLabel', subItem: {name: 'bSubItem'}}],
51-
* $scope.selected = {name: 'aSubItem'};
52-
* - track by is always applied to `value`, with the purpose of preserving the selection,
53-
* (to `item` in this case)
54-
* - to calculate whether an item is selected we do the following:
55-
* 1. apply `track by` to the values in the array, e.g.
56-
* In the example: [1,2]
57-
* 2. apply `track by` to the already selected value in `ngModel`:
58-
* In the example: this is not possible, as `track by` refers to `item.id`, but the selected
59-
* value from `ngModel` is `{name: aSubItem}`.
6084
*
6185
* @param {string} ngModel Assignable angular expression to data-bind to.
6286
* @param {string=} name Property name of the form under which the control is published.

0 commit comments

Comments
 (0)