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

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

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

Powered by Google App Engine
This is Rietveld 408576698