@@ -22,7 +22,7 @@ part of angular.directive;
22
22
selector: 'select[ng-model]' ,
23
23
visibility: Visibility .CHILDREN )
24
24
class InputSelect implements AttachAware {
25
- final expando = new Expando <OptionValue >();
25
+ final options = new Expando <OptionValue >();
26
26
final dom.SelectElement _selectElement;
27
27
final NodeAttrs _attrs;
28
28
final NgModel _model;
@@ -34,23 +34,23 @@ class InputSelect implements AttachAware {
34
34
_SelectMode _mode = new _SelectMode (null , null , null );
35
35
bool _dirty = false ;
36
36
37
- InputSelect (dom.Element this ._selectElement, this ._attrs, this ._model,
38
- this ._scope) {
37
+ InputSelect (dom.Element this ._selectElement, this ._attrs, this ._model, this ._scope) {
39
38
_unknownOption.value = '?' ;
40
- _nullOption = _selectElement.querySelectorAll ('option' )
39
+ _nullOption = _selectElement
40
+ .querySelectorAll ('option' )
41
41
.firstWhere ((o) => o.value == '' , orElse: () => null );
42
42
}
43
43
44
- attach () {
44
+ void attach () {
45
45
_attrs.observe ('multiple' , (value) {
46
+ print ('observe multiple -> $value ' );
46
47
_mode.destroy ();
47
48
if (value == null ) {
48
49
_model.watchCollection = false ;
49
- _mode = new _SingleSelectMode (expando, _selectElement, _model,
50
- _nullOption, _unknownOption);
50
+ _mode = new _SingleSelectMode (options, _selectElement, _model, _nullOption, _unknownOption);
51
51
} else {
52
52
_model.watchCollection = true ;
53
- _mode = new _MultipleSelectionMode (expando , _selectElement, _model);
53
+ _mode = new _MultipleSelectionMode (options , _selectElement, _model);
54
54
}
55
55
_scope.rootScope.domRead (() {
56
56
_mode.onModelChange (_model.viewValue);
@@ -72,7 +72,7 @@ class InputSelect implements AttachAware {
72
72
* This method invalidates the current state of the selector and forces a
73
73
* re-rendering of the options using the [Scope.evalAsync] .
74
74
*/
75
- dirty () {
75
+ void dirty () {
76
76
if (! _dirty) {
77
77
_dirty = true ;
78
78
// TODO(misko): this hack need to delay the rendering until after domRead
@@ -93,56 +93,66 @@ class InputSelect implements AttachAware {
93
93
* expression for the `option.value` attribute and the model. `Selector: option[ng-value]`
94
94
*
95
95
* # Example
96
+ *
96
97
* <select ng-model="robot">
97
98
* <option ng-repeat "r in robots" ng-value="r">{{r.name}}</option>
98
99
* </select>
99
100
*
100
101
* Note: See [InputSelect] for the simpler case where `option.value` is a string.
101
102
*/
102
103
@Decorator (selector: 'option' , module: NgValue .module)
103
- class OptionValue implements AttachAware ,
104
- DetachAware {
104
+ class OptionValue implements AttachAware , DetachAware {
105
105
final InputSelect _inputSelectDirective;
106
106
final dom.Element _element;
107
-
108
- NgValue _ngValue;
107
+ final NgValue _ngValue;
109
108
110
109
OptionValue (this ._element, this ._inputSelectDirective, this ._ngValue) {
111
110
if (_inputSelectDirective != null ) {
112
- _inputSelectDirective.expando [_element] = this ;
111
+ _inputSelectDirective.options [_element] = this ;
113
112
}
114
113
}
115
114
116
- attach () {
115
+ void attach () {
117
116
if (_inputSelectDirective != null ) _inputSelectDirective.dirty ();
118
117
}
119
118
120
- detach () {
119
+ void detach () {
121
120
if (_inputSelectDirective != null ) {
122
121
_inputSelectDirective.dirty ();
123
- _inputSelectDirective.expando [_element] = null ;
122
+ _inputSelectDirective.options [_element] = null ;
124
123
}
125
124
}
126
125
127
- get ngValue => _ngValue.value;
126
+ dynamic get ngValue => _ngValue.value;
128
127
}
129
128
130
129
class _SelectMode {
131
- final Expando <OptionValue > expando ;
130
+ final Expando <OptionValue > options ;
132
131
final dom.SelectElement select;
133
132
final NgModel model;
134
133
135
- _SelectMode (this .expando, this .select, this .model);
134
+ _SelectMode (this .options, this .select, this .model);
135
+
136
+ void onViewChange (event) {}
137
+
138
+ void onModelChange (value) {}
136
139
137
- onViewChange (event) {}
138
- onModelChange (value) {}
139
- destroy () {}
140
+ void destroy () {}
140
141
141
- get _options => select.querySelectorAll ('option' );
142
- _forEachOption (fn, [quitOnReturn = false ]) {
142
+ dom.ElementList get _options => select.querySelectorAll ('option' );
143
+
144
+ /// Executes the `callback` on all the options
145
+ void _forEachOption (Function callback) {
143
146
for (var i = 0 ; i < _options.length; i++ ) {
144
- var retValue = fn (_options[i], i);
145
- if (quitOnReturn && retValue != null ) return retValue;
147
+ callback (_options[i], i);
148
+ }
149
+ }
150
+
151
+ /// Executes the `callback` and returns the result of the first one which does not return `null`
152
+ dynamic _firstOptionWhere (Function callback) {
153
+ for (var i = 0 ; i < _options.length; i++ ) {
154
+ var retValue = callback (_options[i], i);
155
+ if (retValue != null ) return retValue;
146
156
}
147
157
return null ;
148
158
}
@@ -151,41 +161,37 @@ class _SelectMode {
151
161
class _SingleSelectMode extends _SelectMode {
152
162
final dom.OptionElement _unknownOption;
153
163
final dom.OptionElement _nullOption;
154
-
155
164
bool _unknownOptionActive = false ;
156
165
157
- _SingleSelectMode (Expando <OptionValue > expando ,
166
+ _SingleSelectMode (Expando <OptionValue > options ,
158
167
dom.SelectElement select,
159
168
NgModel model,
160
169
this ._nullOption,
161
170
this ._unknownOption)
162
- : super (expando, select, model) {
163
- }
171
+ : super (options, select, model);
164
172
165
- onViewChange (event ) {
166
- var i = 0 ;
167
- model.viewValue = _forEachOption ((option, _) {
173
+ void onViewChange (_ ) {
174
+ print ( 'onViewChange' ) ;
175
+ model.viewValue = _firstOptionWhere ((option, _) {
168
176
if (option.selected) {
169
177
if (option == _nullOption) return null ;
170
- assert (expando [option] != null );
171
- return expando [option].ngValue;
178
+ assert (options [option] != null );
179
+ return options [option].ngValue;
172
180
}
173
- if (option != _unknownOption && option != _nullOption) i++ ;
174
- }, true );
181
+ });
175
182
}
176
183
177
- onModelChange (value) {
178
- var found = false ;
184
+ void onModelChange (value) {
185
+ print ('onModelChange $value ' );
186
+ bool found = false ;
179
187
_forEachOption ((option, i) {
180
188
if (option == _unknownOption) return ;
181
189
var selected;
182
190
if (value == null ) {
183
191
selected = option == _nullOption;
184
192
} else {
185
- OptionValue optionValueDirective = expando[option];
186
- selected = optionValueDirective == null ?
187
- false :
188
- optionValueDirective.ngValue == value;
193
+ OptionValue optionValue = options[option];
194
+ selected = optionValue == null ? false : optionValue.ngValue == value;
189
195
}
190
196
found = found || selected;
191
197
option.selected = selected;
@@ -207,26 +213,26 @@ class _SingleSelectMode extends _SelectMode {
207
213
}
208
214
209
215
class _MultipleSelectionMode extends _SelectMode {
210
- _MultipleSelectionMode (Expando <OptionValue > expando ,
216
+ _MultipleSelectionMode (Expando <OptionValue > options ,
211
217
dom.SelectElement select,
212
218
NgModel model)
213
- : super (expando , select, model);
219
+ : super (options , select, model);
214
220
215
- onViewChange (event ) {
221
+ void onViewChange (_ ) {
216
222
var selected = [];
217
223
218
- _forEachOption ((o, i ) {
219
- if (o.selected) selected.add (expando [o].ngValue);
224
+ _forEachOption ((o, _ ) {
225
+ if (o.selected) selected.add (options [o].ngValue);
220
226
});
221
227
model.viewValue = selected;
222
228
}
223
229
224
- onModelChange (List selectedValues) {
225
- Function fn = (o, i ) => o.selected = null ;
230
+ void onModelChange (List selectedValues) {
231
+ Function fn = (o, _ ) => o.selected = null ;
226
232
227
233
if (selectedValues is List ) {
228
234
fn = (o, i) {
229
- var selected = expando [o];
235
+ var selected = options [o];
230
236
return selected == null ?
231
237
false :
232
238
o.selected = selectedValues.contains (selected.ngValue);
0 commit comments