@@ -70,6 +70,52 @@ angular.module('material.components.select', [
70
70
* </md-select>
71
71
* </md-input-container>
72
72
* </hljs>
73
+ *
74
+ * ## Selects and object equality
75
+ * When using a `md-select` to pick from a list of objects, it is important to realize how javascript handles
76
+ * equality. Consider the following example:
77
+ * <hljs lang="js">
78
+ * angular.controller('MyCtrl', function($scope) {
79
+ * $scope.users = [
80
+ * { id: 1, name: 'Bob' },
81
+ * { id: 2, name: 'Alice' },
82
+ * { id: 3, name: 'Steve' }
83
+ * ];
84
+ * $scope.selectedUser = { id: 1, name: 'Bob' };
85
+ * });
86
+ * </hljs>
87
+ * <hljs lang="html">
88
+ * <div ng-controller="MyCtrl">
89
+ * <md-select ng-model="selectedUser">
90
+ * <md-option ng-value="user" ng-repeat="user in users">{{ user.name }}</md-option>
91
+ * </md-select>
92
+ * </div>
93
+ * </hljs>
94
+ *
95
+ * At first one might expect that the select should be populated with "Bob" as the selected user. However,
96
+ * this is not true. To determine whether something is selected,
97
+ * `ngModelController` is looking at whether `$scope.selectedUser == (any user in $scope.users);`;
98
+ *
99
+ * Javascript's `==` operator does not check for deep equality (ie. that all properties
100
+ * on the object are the same), but instead whether the objects are *the same object in memory*.
101
+ * In this case, we have two instances of identical objects, but they exist in memory as unique
102
+ * entities. Because of this, the select will have no value populated for a selected user.
103
+ *
104
+ * To get around this, `ngModelController` provides a `track by` option that allows us to specify a different
105
+ * expression which will be used for the equality operator. As such, we can update our `html` to
106
+ * make use of this by specifying the `ng-model-options="{trackBy: '$value.id'}"` on the `md-select`
107
+ * element. This converts our equality expression to be
108
+ * `$scope.selectedUser.id == (any id in $scope.users.map(function(u) { return u.id; }));`
109
+ * which results in Bob being selected as desired.
110
+ *
111
+ * Working HTML:
112
+ * <hljs lang="html">
113
+ * <div ng-controller="MyCtrl">
114
+ * <md-select ng-model="selectedUser" ng-model-options="{trackBy: '$value.id'}">
115
+ * <md-option ng-value="user" ng-repeat="user in users">{{ user.name }}</md-option>
116
+ * </md-select>
117
+ * </div>
118
+ * </hljs>
73
119
*/
74
120
function SelectDirective ( $mdSelect , $mdUtil , $mdTheming , $mdAria , $compile , $parse ) {
75
121
return {
0 commit comments