Skip to content

Commit d3f9465

Browse files
committed
refactor(InputSelect): code cleanup
1 parent ace5aaf commit d3f9465

File tree

1 file changed

+58
-52
lines changed

1 file changed

+58
-52
lines changed

lib/directive/ng_model_select.dart

Lines changed: 58 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ part of angular.directive;
2222
selector: 'select[ng-model]',
2323
visibility: Visibility.CHILDREN)
2424
class InputSelect implements AttachAware {
25-
final expando = new Expando<OptionValue>();
25+
final options = new Expando<OptionValue>();
2626
final dom.SelectElement _selectElement;
2727
final NodeAttrs _attrs;
2828
final NgModel _model;
@@ -34,23 +34,23 @@ class InputSelect implements AttachAware {
3434
_SelectMode _mode = new _SelectMode(null, null, null);
3535
bool _dirty = false;
3636

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) {
3938
_unknownOption.value = '?';
40-
_nullOption = _selectElement.querySelectorAll('option')
39+
_nullOption = _selectElement
40+
.querySelectorAll('option')
4141
.firstWhere((o) => o.value == '', orElse: () => null);
4242
}
4343

44-
attach() {
44+
void attach() {
4545
_attrs.observe('multiple', (value) {
46+
print('observe multiple -> $value');
4647
_mode.destroy();
4748
if (value == null) {
4849
_model.watchCollection = false;
49-
_mode = new _SingleSelectMode(expando, _selectElement, _model,
50-
_nullOption, _unknownOption);
50+
_mode = new _SingleSelectMode(options, _selectElement, _model, _nullOption, _unknownOption);
5151
} else {
5252
_model.watchCollection = true;
53-
_mode = new _MultipleSelectionMode(expando, _selectElement, _model);
53+
_mode = new _MultipleSelectionMode(options, _selectElement, _model);
5454
}
5555
_scope.rootScope.domRead(() {
5656
_mode.onModelChange(_model.viewValue);
@@ -72,7 +72,7 @@ class InputSelect implements AttachAware {
7272
* This method invalidates the current state of the selector and forces a
7373
* re-rendering of the options using the [Scope.evalAsync].
7474
*/
75-
dirty() {
75+
void dirty() {
7676
if (!_dirty) {
7777
_dirty = true;
7878
// TODO(misko): this hack need to delay the rendering until after domRead
@@ -93,56 +93,66 @@ class InputSelect implements AttachAware {
9393
* expression for the `option.value` attribute and the model. `Selector: option[ng-value]`
9494
*
9595
* # Example
96+
*
9697
* <select ng-model="robot">
9798
* <option ng-repeat "r in robots" ng-value="r">{{r.name}}</option>
9899
* </select>
99100
*
100101
* Note: See [InputSelect] for the simpler case where `option.value` is a string.
101102
*/
102103
@Decorator(selector: 'option', module: NgValue.module)
103-
class OptionValue implements AttachAware,
104-
DetachAware {
104+
class OptionValue implements AttachAware, DetachAware {
105105
final InputSelect _inputSelectDirective;
106106
final dom.Element _element;
107-
108-
NgValue _ngValue;
107+
final NgValue _ngValue;
109108

110109
OptionValue(this._element, this._inputSelectDirective, this._ngValue) {
111110
if (_inputSelectDirective != null) {
112-
_inputSelectDirective.expando[_element] = this;
111+
_inputSelectDirective.options[_element] = this;
113112
}
114113
}
115114

116-
attach() {
115+
void attach() {
117116
if (_inputSelectDirective != null) _inputSelectDirective.dirty();
118117
}
119118

120-
detach() {
119+
void detach() {
121120
if (_inputSelectDirective != null) {
122121
_inputSelectDirective.dirty();
123-
_inputSelectDirective.expando[_element] = null;
122+
_inputSelectDirective.options[_element] = null;
124123
}
125124
}
126125

127-
get ngValue => _ngValue.value;
126+
dynamic get ngValue => _ngValue.value;
128127
}
129128

130129
class _SelectMode {
131-
final Expando<OptionValue> expando;
130+
final Expando<OptionValue> options;
132131
final dom.SelectElement select;
133132
final NgModel model;
134133

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) {}
136139

137-
onViewChange(event) {}
138-
onModelChange(value) {}
139-
destroy() {}
140+
void destroy() {}
140141

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) {
143146
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;
146156
}
147157
return null;
148158
}
@@ -151,41 +161,37 @@ class _SelectMode {
151161
class _SingleSelectMode extends _SelectMode {
152162
final dom.OptionElement _unknownOption;
153163
final dom.OptionElement _nullOption;
154-
155164
bool _unknownOptionActive = false;
156165

157-
_SingleSelectMode(Expando<OptionValue> expando,
166+
_SingleSelectMode(Expando<OptionValue> options,
158167
dom.SelectElement select,
159168
NgModel model,
160169
this._nullOption,
161170
this._unknownOption)
162-
: super(expando, select, model) {
163-
}
171+
: super(options, select, model);
164172

165-
onViewChange(event) {
166-
var i = 0;
167-
model.viewValue = _forEachOption((option, _) {
173+
void onViewChange(_) {
174+
print ('onViewChange');
175+
model.viewValue = _firstOptionWhere((option, _) {
168176
if (option.selected) {
169177
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;
172180
}
173-
if (option != _unknownOption && option != _nullOption) i++;
174-
}, true);
181+
});
175182
}
176183

177-
onModelChange(value) {
178-
var found = false;
184+
void onModelChange(value) {
185+
print('onModelChange $value');
186+
bool found = false;
179187
_forEachOption((option, i) {
180188
if (option == _unknownOption) return;
181189
var selected;
182190
if (value == null) {
183191
selected = option == _nullOption;
184192
} 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;
189195
}
190196
found = found || selected;
191197
option.selected = selected;
@@ -207,26 +213,26 @@ class _SingleSelectMode extends _SelectMode {
207213
}
208214

209215
class _MultipleSelectionMode extends _SelectMode {
210-
_MultipleSelectionMode(Expando<OptionValue> expando,
216+
_MultipleSelectionMode(Expando<OptionValue> options,
211217
dom.SelectElement select,
212218
NgModel model)
213-
: super(expando, select, model);
219+
: super(options, select, model);
214220

215-
onViewChange(event) {
221+
void onViewChange(_) {
216222
var selected = [];
217223

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);
220226
});
221227
model.viewValue = selected;
222228
}
223229

224-
onModelChange(List selectedValues) {
225-
Function fn = (o, i) => o.selected = null;
230+
void onModelChange(List selectedValues) {
231+
Function fn = (o, _) => o.selected = null;
226232

227233
if (selectedValues is List) {
228234
fn = (o, i) {
229-
var selected = expando[o];
235+
var selected = options[o];
230236
return selected == null ?
231237
false :
232238
o.selected = selectedValues.contains(selected.ngValue);

0 commit comments

Comments
 (0)