From d3f94657e17c9cb3379aacb0eddc1d166e696563 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Mon, 4 Aug 2014 17:05:10 +0200 Subject: [PATCH] refactor(InputSelect): code cleanup --- lib/directive/ng_model_select.dart | 110 +++++++++++++++-------------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/lib/directive/ng_model_select.dart b/lib/directive/ng_model_select.dart index c44139de0..6c205c5bb 100644 --- a/lib/directive/ng_model_select.dart +++ b/lib/directive/ng_model_select.dart @@ -22,7 +22,7 @@ part of angular.directive; selector: 'select[ng-model]', visibility: Visibility.CHILDREN) class InputSelect implements AttachAware { - final expando = new Expando(); + final options = new Expando(); final dom.SelectElement _selectElement; final NodeAttrs _attrs; final NgModel _model; @@ -34,23 +34,23 @@ class InputSelect implements AttachAware { _SelectMode _mode = new _SelectMode(null, null, null); bool _dirty = false; - InputSelect(dom.Element this._selectElement, this._attrs, this._model, - this._scope) { + InputSelect(dom.Element this._selectElement, this._attrs, this._model, this._scope) { _unknownOption.value = '?'; - _nullOption = _selectElement.querySelectorAll('option') + _nullOption = _selectElement + .querySelectorAll('option') .firstWhere((o) => o.value == '', orElse: () => null); } - attach() { + void attach() { _attrs.observe('multiple', (value) { + print('observe multiple -> $value'); _mode.destroy(); if (value == null) { _model.watchCollection = false; - _mode = new _SingleSelectMode(expando, _selectElement, _model, - _nullOption, _unknownOption); + _mode = new _SingleSelectMode(options, _selectElement, _model, _nullOption, _unknownOption); } else { _model.watchCollection = true; - _mode = new _MultipleSelectionMode(expando, _selectElement, _model); + _mode = new _MultipleSelectionMode(options, _selectElement, _model); } _scope.rootScope.domRead(() { _mode.onModelChange(_model.viewValue); @@ -72,7 +72,7 @@ class InputSelect implements AttachAware { * This method invalidates the current state of the selector and forces a * re-rendering of the options using the [Scope.evalAsync]. */ - dirty() { + void dirty() { if (!_dirty) { _dirty = true; // TODO(misko): this hack need to delay the rendering until after domRead @@ -93,6 +93,7 @@ class InputSelect implements AttachAware { * expression for the `option.value` attribute and the model. `Selector: option[ng-value]` * * # Example + * * @@ -100,49 +101,58 @@ class InputSelect implements AttachAware { * Note: See [InputSelect] for the simpler case where `option.value` is a string. */ @Decorator(selector: 'option', module: NgValue.module) -class OptionValue implements AttachAware, - DetachAware { +class OptionValue implements AttachAware, DetachAware { final InputSelect _inputSelectDirective; final dom.Element _element; - - NgValue _ngValue; + final NgValue _ngValue; OptionValue(this._element, this._inputSelectDirective, this._ngValue) { if (_inputSelectDirective != null) { - _inputSelectDirective.expando[_element] = this; + _inputSelectDirective.options[_element] = this; } } - attach() { + void attach() { if (_inputSelectDirective != null) _inputSelectDirective.dirty(); } - detach() { + void detach() { if (_inputSelectDirective != null) { _inputSelectDirective.dirty(); - _inputSelectDirective.expando[_element] = null; + _inputSelectDirective.options[_element] = null; } } - get ngValue => _ngValue.value; + dynamic get ngValue => _ngValue.value; } class _SelectMode { - final Expando expando; + final Expando options; final dom.SelectElement select; final NgModel model; - _SelectMode(this.expando, this.select, this.model); + _SelectMode(this.options, this.select, this.model); + + void onViewChange(event) {} + + void onModelChange(value) {} - onViewChange(event) {} - onModelChange(value) {} - destroy() {} + void destroy() {} - get _options => select.querySelectorAll('option'); - _forEachOption(fn, [quitOnReturn = false]) { + dom.ElementList get _options => select.querySelectorAll('option'); + + /// Executes the `callback` on all the options + void _forEachOption(Function callback) { for (var i = 0; i < _options.length; i++) { - var retValue = fn(_options[i], i); - if (quitOnReturn && retValue != null) return retValue; + callback(_options[i], i); + } + } + + /// Executes the `callback` and returns the result of the first one which does not return `null` + dynamic _firstOptionWhere(Function callback) { + for (var i = 0; i < _options.length; i++) { + var retValue = callback(_options[i], i); + if (retValue != null) return retValue; } return null; } @@ -151,41 +161,37 @@ class _SelectMode { class _SingleSelectMode extends _SelectMode { final dom.OptionElement _unknownOption; final dom.OptionElement _nullOption; - bool _unknownOptionActive = false; - _SingleSelectMode(Expando expando, + _SingleSelectMode(Expando options, dom.SelectElement select, NgModel model, this._nullOption, this._unknownOption) - : super(expando, select, model) { - } + : super(options, select, model); - onViewChange(event) { - var i = 0; - model.viewValue = _forEachOption((option, _) { + void onViewChange(_) { + print ('onViewChange'); + model.viewValue = _firstOptionWhere((option, _) { if (option.selected) { if (option == _nullOption) return null; - assert(expando[option] != null); - return expando[option].ngValue; + assert(options[option] != null); + return options[option].ngValue; } - if (option != _unknownOption && option != _nullOption) i++; - }, true); + }); } - onModelChange(value) { - var found = false; + void onModelChange(value) { + print('onModelChange $value'); + bool found = false; _forEachOption((option, i) { if (option == _unknownOption) return; var selected; if (value == null) { selected = option == _nullOption; } else { - OptionValue optionValueDirective = expando[option]; - selected = optionValueDirective == null ? - false : - optionValueDirective.ngValue == value; + OptionValue optionValue = options[option]; + selected = optionValue == null ? false : optionValue.ngValue == value; } found = found || selected; option.selected = selected; @@ -207,26 +213,26 @@ class _SingleSelectMode extends _SelectMode { } class _MultipleSelectionMode extends _SelectMode { - _MultipleSelectionMode(Expando expando, + _MultipleSelectionMode(Expando options, dom.SelectElement select, NgModel model) - : super(expando, select, model); + : super(options, select, model); - onViewChange(event) { + void onViewChange(_) { var selected = []; - _forEachOption((o, i) { - if (o.selected) selected.add(expando[o].ngValue); + _forEachOption((o, _) { + if (o.selected) selected.add(options[o].ngValue); }); model.viewValue = selected; } - onModelChange(List selectedValues) { - Function fn = (o, i) => o.selected = null; + void onModelChange(List selectedValues) { + Function fn = (o, _) => o.selected = null; if (selectedValues is List) { fn = (o, i) { - var selected = expando[o]; + var selected = options[o]; return selected == null ? false : o.selected = selectedValues.contains(selected.ngValue);