Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: third_party/pkg/angular/lib/directive/input_select.dart

Issue 180843004: Revert revision 33053 (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 part of angular.directive; 1 part of angular.directive;
2 2
3 typedef dynamic ItemEval(dynamic item, num index); 3 typedef dynamic ItemEval(dynamic item, num index);
4 4
5 /** 5 /**
6 * HTML [SELECT] element with angular data-binding if used with 6 * HTML [SELECT] element with angular data-binding if used with [NgModelDirectiv e].
7 * [NgModelDirective].
8 * 7 *
9 * The [NgModelDirective] will receive the currently selected item. The binding 8 * The [NgModelDirective] will receive the currently selected item. The binding is
10 * is performed on the [OPTION].[value] property. An empty [OPTION].[value] is 9 * performed on the [OPTION].[value] property.
11 * treated as null. 10 * An empty [OPTION].[value] is treated as null.
12 * 11 *
13 * If you the model contains value which does not map to any [OPTION] then a new 12 * If you the model contains value which does not map to any [OPTION] then a new
14 * unknown [OPTION] is inserted into the list. Once the model points to an 13 * unknown [OPTION] is inserted into the list. Once the model points to an exist ing
15 * existing [OPTION] the unknown [OPTION] is removed. 14 * [OPTION] the unknown [OPTION] is removed.
16 * 15 *
17 * Becouse [OPTION].[value] attribute is a string, the model is bound to a 16 * Becouse [OPTION].[value] attribute is a string, the model is bound to a strin g.
18 * string. If there is need to bind to an object then [OptionValueDirective] 17 * If there is need to bind to an object then [OptionValueDirective] should be u sed.
19 * should be used.
20 * 18 *
21 */ 19 */
22 @NgDirective( 20 @NgDirective(
23 selector: 'select[ng-model]', 21 selector: 'select[ng-model]',
24 visibility: NgDirective.CHILDREN_VISIBILITY) 22 visibility: NgDirective.CHILDREN_VISIBILITY
23 )
25 class InputSelectDirective implements NgAttachAware { 24 class InputSelectDirective implements NgAttachAware {
26 final Expando<OptionValueDirective> expando = 25 final Expando<OptionValueDirective> expando = new Expando<OptionValueDirective >();
27 new Expando<OptionValueDirective>();
28 final dom.SelectElement _selectElement; 26 final dom.SelectElement _selectElement;
29 final NodeAttrs _attrs; 27 final NodeAttrs _attrs;
30 final NgModel _model; 28 final NgModel _model;
31 final Scope _scope; 29 final Scope _scope;
32 30
33 final dom.OptionElement _unknownOption = new dom.OptionElement(); 31 final dom.OptionElement _unknownOption = new dom.OptionElement();
34 dom.OptionElement _nullOption; 32 dom.OptionElement _nullOption;
35 33
36 _SelectMode _mode = new _SelectMode(null, null, null); 34 _SelectMode _mode = new _SelectMode(null, null, null);
37 bool _dirty = false; 35 bool _dirty = false;
38 36
39 InputSelectDirective(dom.Element this._selectElement, this._attrs, this._model , 37 InputSelectDirective(dom.Element this._selectElement, this._attrs, this._model , this._scope) {
40 this._scope) {
41 _unknownOption.value = '?'; 38 _unknownOption.value = '?';
42 _unknownOption.text = ''; // Explicit due to dartbug.com/14407 39 _unknownOption.text = ''; // Explicit due to dartbug.com/14407
43 _selectElement.querySelectorAll('option').forEach((o) { 40 _selectElement.querySelectorAll('option').forEach((o) {
44 if (_nullOption == null && o.value == '') { 41 if (_nullOption == null && o.value == '') {
45 _nullOption = o; 42 _nullOption = o;
46 } 43 }
47 }); 44 });
48 } 45 }
49 46
50 attach() { 47 attach() {
51 _attrs.observe('multiple', (value) { 48 _attrs.observe('multiple', (value) {
52 _mode.destroy(); 49 _mode.destroy();
53 if (value == null) { 50 if (value == null) {
54 _model.watchCollection = false; 51 _model.watchCollection = false;
55 _mode = new _SingleSelectMode(expando, _selectElement, _model, _nullOpti on, _unknownOption); 52 _mode = new _SingleSelectMode(expando, _selectElement, _model, _nullOpti on, _unknownOption);
56 } else { 53 } else {
57 _model.watchCollection = true; 54 _model.watchCollection = true;
58 _mode = new _MultipleSelectionMode(expando, _selectElement, _model); 55 _mode = new _MultipleSelectionMode(expando, _selectElement, _model);
59 } 56 }
60 _mode.onModelChange(_model.viewValue); 57 _mode.onModelChange(_model.viewValue);
61 }); 58 });
62 59
63 _selectElement.onChange.listen((event) => _mode.onViewChange(event)); 60 _selectElement.onChange.listen((event) => _mode.onViewChange(event));
64 _model.render = (value) { 61 _model.render = (value) => _mode.onModelChange(value);
65 // TODO(misko): this hack need to delay the rendering until after domRead
66 // because the modelChange reads from the DOM. We should be able to render
67 // without DOM changes.
68 _scope.rootScope.domRead(() {
69 _scope.rootScope.domWrite(() => _mode.onModelChange(value));
70 });
71 };
72 } 62 }
73 63
74 /** 64 /**
75 * This method invalidates the current state of the selector and forces a 65 * This method invalidates the current state of the selector and forces a re-r endering of the
76 * re-rendering of the options using the [Scope.evalAsync]. 66 * options using the [Scope.$evalAsync].
77 */ 67 */
78 dirty() { 68 dirty() {
79 if (!_dirty) { 69 if (!_dirty) {
80 _dirty = true; 70 _dirty = true;
81 // TODO(misko): this hack need to delay the rendering until after domRead 71 _scope.$evalAsync(() {
82 // becouse the modelChange reads from the DOM. We should be able to render 72 _dirty = false;
83 // without DOM changes. 73 _mode.onModelChange(_model.viewValue);
84 _scope.rootScope.domRead(() {
85 _scope.rootScope.domWrite(() {
86 _dirty = false;
87 _mode.onModelChange(_model.viewValue);
88 });
89 }); 74 });
90 } 75 }
91 } 76 }
92 } 77 }
93 78
94 /** 79 /**
95 * Since the [value] attribute of the [OPTION] can only be a string, Angular 80 * Since the [value] attirbute of the [OPTION] can only be a string, Angular pro vides
96 * provides [ng-value] which allows binding to any expression. 81 * [ng-value] which allows binding to any expression.
97 * 82 *
98 */ 83 */
99 @NgDirective( 84 @NgDirective(
100 selector: 'option') 85 selector: 'option',
101 class OptionValueDirective implements NgAttachAware, 86 publishTypes: const [TextChangeListener],
102 NgDetachAware { 87 map: const {'ng-value': '&ngValue'}
88 )
89 class OptionValueDirective implements TextChangeListener, NgAttachAware, NgDetac hAware {
103 final InputSelectDirective _inputSelectDirective; 90 final InputSelectDirective _inputSelectDirective;
104 final dom.Element _element; 91 final NodeAttrs _attrs;
105 92
106 NgValue _ngValue; 93 Getter _ngValue;
107 94
108 OptionValueDirective(this._element, this._inputSelectDirective, this._ngValue) { 95 OptionValueDirective(this._attrs, this._inputSelectDirective) {
109 if (_inputSelectDirective != null) { 96 if (_inputSelectDirective != null) {
110 _inputSelectDirective.expando[_element] = this; 97 _inputSelectDirective.expando[_attrs.element] = this;
111 } 98 }
112 } 99 }
113 100
114 attach() { 101 attach() {
115 if (_inputSelectDirective != null) { 102 if (_inputSelectDirective != null) {
103 this._attrs.observe('value', (_) => _inputSelectDirective.dirty());
104 }
105 }
106
107 call(String text) {
108 if (_inputSelectDirective != null) {
116 _inputSelectDirective.dirty(); 109 _inputSelectDirective.dirty();
117 } 110 }
118 } 111 }
119 112
120 detach() { 113 detach() {
121 if (_inputSelectDirective != null) { 114 if (_inputSelectDirective != null) {
122 _inputSelectDirective.dirty(); 115 _inputSelectDirective.dirty();
123 _inputSelectDirective.expando[_element] = null; 116 _inputSelectDirective.expando[_attrs.element] = null;
124 } 117 }
125 } 118 }
126 119
127 get ngValue => _ngValue.readValue(_element); 120 set ngValue(Getter value) => _ngValue = value;
121 get ngValue =>
122 _attrs['ng-value'] is String ? _ngValue() : (_attrs.element as dom.OptionEle ment).value;
128 } 123 }
129 124
130 class _SelectMode { 125 class _SelectMode {
131 final Expando<OptionValueDirective> expando; 126 final Expando<OptionValueDirective> expando;
132 final dom.SelectElement select; 127 final dom.SelectElement select;
133 final NgModel model; 128 final NgModel model;
134 129
135 _SelectMode(this.expando, this.select, this.model); 130 _SelectMode(this.expando, this.select, this.model);
136 131
137 onViewChange(event) {} 132 onViewChange(event) {}
138 onModelChange(value) {} 133 onModelChange(value) {}
139 destroy() {} 134 destroy() {}
140 135
141 get _options => select.querySelectorAll('option'); 136 get _options => select.querySelectorAll('option');
142 _forEachOption(fn, [quiteOnReturn = false]) { 137 _forEachOption(fn, [quiteOnReturn = false]) {
143 for (var i = 0; i < _options.length; i++) { 138 for(var os = _options, i = 0, ii = os.length; i < ii; i++) {
144 var retValue = fn(_options[i], i); 139 var retValue = fn(os[i], i);
145 if (quiteOnReturn && retValue != null) return retValue; 140 if (quiteOnReturn && retValue != null) {
141 return retValue;
142 }
146 } 143 }
147 return null; 144 return null;
148 } 145 }
149 } 146 }
150 147
151 class _SingleSelectMode extends _SelectMode { 148 class _SingleSelectMode extends _SelectMode {
152 final dom.OptionElement _unknownOption; 149 final dom.OptionElement _unknownOption;
153 final dom.OptionElement _nullOption; 150 final dom.OptionElement _nullOption;
154 151
155 bool _unknownOptionActive = false; 152 bool _unknownOptionActive = false;
156 153
157 _SingleSelectMode(Expando<OptionValueDirective> expando, 154 _SingleSelectMode(Expando<OptionValueDirective> expando,
158 dom.SelectElement select, 155 dom.SelectElement select,
159 NgModel model, 156 NgModel model,
160 this._nullOption, 157 this._nullOption,
161 this._unknownOption 158 this._unknownOption
162 ): super(expando, select, model) { 159 ): super(expando, select, model) {
163 } 160 }
164 161
165 onViewChange(event) { 162 onViewChange(event) {
166 var i = 0; 163 var i = 0;
167 model.viewValue = _forEachOption((option, _) { 164 model.viewValue = _forEachOption((option, _) {
168 if (option.selected) { 165 if (option.selected) {
169 return option == _nullOption ? null : expando[option].ngValue; 166 return option == _nullOption ? null : expando[option].ngValue;
170 } 167 }
171 if (option != _unknownOption && option != _nullOption) i++; 168 if (option != _unknownOption && option != _nullOption) {
169 i++;
170 }
172 }, true); 171 }, true);
173 } 172 }
174 173
175 onModelChange(value) { 174 onModelChange(value) {
176 var found = false; 175 var found = false;
177 _forEachOption((option, i) { 176 _forEachOption((option, i) {
178 if (option == _unknownOption) return; 177 if (option == _unknownOption) return;
179 var selected; 178 var selected;
180 if (value == null) { 179 if (value == null) {
181 selected = option == _nullOption; 180 selected = option == _nullOption;
(...skipping 16 matching lines...) Expand all
198 _unknownOption.remove(); 197 _unknownOption.remove();
199 _unknownOptionActive = false; 198 _unknownOptionActive = false;
200 } 199 }
201 } 200 }
202 } 201 }
203 } 202 }
204 203
205 class _MultipleSelectionMode extends _SelectMode { 204 class _MultipleSelectionMode extends _SelectMode {
206 _MultipleSelectionMode(Expando<OptionValueDirective> expando, 205 _MultipleSelectionMode(Expando<OptionValueDirective> expando,
207 dom.SelectElement select, 206 dom.SelectElement select,
208 NgModel model) 207 NgModel model
209 : super(expando, select, model); 208 ): super(expando, select, model);
210 209
211 onViewChange(event) { 210 onViewChange(event) {
212 var selected = []; 211 var selected = [];
213 212
214 _forEachOption((o, i) { 213 _forEachOption((o, i) {
215 if (o.selected) selected.add(expando[o].ngValue); 214 if (o.selected) {
215 selected.add(expando[o].ngValue);
216 }
216 }); 217 });
217 model.viewValue = selected; 218 model.viewValue = selected;
218 } 219 }
219 220
220 onModelChange(List selectedValues) { 221 onModelChange(List selectedValues) {
221 Function fn = (o, i) => o.selected = null; 222 Function fn = (o, i) => o.selected = null;
222 223
223 if (selectedValues is List) { 224 if (selectedValues is List) {
224 fn = (o, i) { 225 fn = (o, i) => o.selected = selectedValues.contains(expando[o].ngValue);
225 var selected = expando[o];
226 if (selected == null) {
227 return false;
228 } else {
229 return o.selected = selectedValues.contains(selected.ngValue);
230 }
231 };
232 } 226 }
233 227
234 _forEachOption(fn); 228 _forEachOption(fn);
235 } 229 }
236 } 230 }
OLDNEW
« no previous file with comments | « third_party/pkg/angular/lib/core_dom/selector.dart ('k') | third_party/pkg/angular/lib/directive/module.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698