Skip to content

Commit 4d1ed50

Browse files
committed
refactor(forms): refactored forms to user Query to get html validators
1 parent 85b8a15 commit 4d1ed50

File tree

11 files changed

+104
-37
lines changed

11 files changed

+104
-37
lines changed

modules/angular2/src/core/compiler/base_query_list.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ export class BaseQueryList<T> {
3838
removeCallback(callback) { ListWrapper.remove(this._callbacks, callback); }
3939

4040
get length() { return this._results.length; }
41-
4241
get first() { return ListWrapper.first(this._results); }
43-
4442
get last() { return ListWrapper.last(this._results); }
4543
}

modules/angular2/src/facade/collection.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ class ListWrapper {
184184

185185
bool isListLikeIterable(obj) => obj is Iterable;
186186

187+
List<T> iterableToList(Iterable<T> ii) => ii.toList();
188+
187189
void iterateListLike(iter, fn(item)) {
188190
assert(iter is Iterable);
189191
for (var item in iter) {

modules/angular2/src/facade/collection.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,13 @@ export function iterateListLike(obj, fn: Function) {
253253
}
254254
}
255255
}
256-
256+
export function iterableToList<T>(ii:Iterable<T>):List<T> {
257+
var res = [];
258+
for (var i of ii) {
259+
res.push(i);
260+
}
261+
return res;
262+
}
257263

258264
// Safari and Internet Explorer do not support the iterable parameter to the
259265
// Set constructor. We work around that by manually adding the items.

modules/angular2/src/forms/directives.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export {ControlValueAccessor} from './directives/control_value_accessor';
2424
export {DefaultValueAccessor} from './directives/default_value_accessor';
2525
export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
2626
export {SelectControlValueAccessor} from './directives/select_control_value_accessor';
27-
export {NgRequiredValidator} from './directives/validators';
27+
export {NgValidator, NgRequiredValidator} from './directives/validators';
2828

2929
/**
3030
*

modules/angular2/src/forms/directives/ng_control.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {ControlValueAccessor} from './control_value_accessor';
2-
import {Validators} from '../validators';
32
import {Control} from '../model';
43

54
/**
@@ -12,11 +11,10 @@ import {Control} from '../model';
1211
export class NgControl {
1312
name: string = null;
1413
valueAccessor: ControlValueAccessor = null;
15-
validator: Function;
1614

15+
get validator(): Function { return null; }
1716
get path(): List<string> { return null; }
1817
get control(): Control { return null; }
19-
constructor() { this.validator = Validators.nullValidator; }
2018

2119
viewToModelUpdate(newValue: any): void {}
2220
}

modules/angular2/src/forms/directives/ng_control_name.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import {CONST_EXPR} from 'angular2/src/facade/lang';
22
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
33
import {List, StringMapWrapper, StringMap} from 'angular2/src/facade/collection';
4-
import {Directive, Ancestor, onDestroy, onChange} from 'angular2/angular2';
4+
5+
import {Directive, Ancestor, onDestroy, onChange, Query, QueryList} from 'angular2/angular2';
56
import {forwardRef, Binding, Inject} from 'angular2/di';
67

78
import {ControlContainer} from './control_container';
89
import {NgControl} from './ng_control';
9-
import {controlPath} from './shared';
10+
import {NgValidator} from './validators';
11+
import {controlPath, composeNgValidator} from './shared';
1012
import {Control} from '../model';
1113

1214
const controlNameBinding =
@@ -82,13 +84,17 @@ export class NgControlName extends NgControl {
8284
_parent: ControlContainer;
8385
ngModel: EventEmitter;
8486
model: any;
87+
ngValidators: QueryList<NgValidator>;
8588
_added: boolean;
8689

87-
constructor(@Ancestor() _parent: ControlContainer) {
90+
// Scope the query once https://github.com/angular/angular/issues/2603 is fixed
91+
constructor(@Ancestor() parent: ControlContainer,
92+
@Query(NgValidator) ngValidators: QueryList<NgValidator>) {
8893
super();
89-
this._parent = _parent;
94+
this._parent = parent;
9095
this.ngModel = new EventEmitter();
9196
this._added = false;
97+
this.ngValidators = ngValidators;
9298
}
9399

94100
onChange(c: StringMap<string, any>) {
@@ -101,7 +107,6 @@ export class NgControlName extends NgControl {
101107
}
102108
}
103109

104-
105110
onDestroy() { this.formDirective.removeControl(this); }
106111

107112
viewToModelUpdate(newValue: any): void { ObservableWrapper.callNext(this.ngModel, newValue); }
@@ -111,4 +116,6 @@ export class NgControlName extends NgControl {
111116
get formDirective(): any { return this._parent.formDirective; }
112117

113118
get control(): Control { return this.formDirective.getControl(this); }
119+
120+
get validator(): Function { return composeNgValidator(this.ngValidators); }
114121
}

modules/angular2/src/forms/directives/ng_form_control.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import {CONST_EXPR} from 'angular2/src/facade/lang';
22
import {StringMapWrapper} from 'angular2/src/facade/collection';
33
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
44

5-
import {Directive, Ancestor, onChange} from 'angular2/angular2';
5+
import {Directive, Ancestor, onChange, Query, QueryList} from 'angular2/angular2';
66
import {forwardRef, Binding} from 'angular2/di';
77

88
import {NgControl} from './ng_control';
99
import {Control} from '../model';
10-
import {setUpControl} from './shared';
10+
import {NgValidator} from './validators';
11+
import {setUpControl, composeNgValidator} from './shared';
1112

1213
const formControlBinding =
1314
CONST_EXPR(new Binding(NgControl, {toAlias: forwardRef(() => NgFormControl)}));
@@ -72,11 +73,14 @@ export class NgFormControl extends NgControl {
7273
ngModel: EventEmitter;
7374
_added: boolean;
7475
model: any;
76+
ngValidators: QueryList<NgValidator>;
7577

76-
constructor() {
78+
// Scope the query once https://github.com/angular/angular/issues/2603 is fixed
79+
constructor(@Query(NgValidator) ngValidators: QueryList<NgValidator>) {
7780
super();
7881
this.ngModel = new EventEmitter();
7982
this._added = false;
83+
this.ngValidators = ngValidators;
8084
}
8185

8286
onChange(c) {
@@ -90,9 +94,11 @@ export class NgFormControl extends NgControl {
9094
}
9195
}
9296

97+
get path(): List<string> { return []; }
98+
9399
get control(): Control { return this.form; }
94100

95-
get path(): List<string> { return []; }
101+
get validator(): Function { return composeNgValidator(this.ngValidators); }
96102

97103
viewToModelUpdate(newValue: any): void { ObservableWrapper.callNext(this.ngModel, newValue); }
98104
}

modules/angular2/src/forms/directives/ng_model.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import {CONST_EXPR} from 'angular2/src/facade/lang';
22
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
33
import {StringMapWrapper} from 'angular2/src/facade/collection';
44

5-
import {Directive, Ancestor, onChange} from 'angular2/angular2';
5+
import {Directive, Ancestor, onChange, QueryList, Query} from 'angular2/angular2';
66
import {forwardRef, Binding} from 'angular2/di';
77

88
import {NgControl} from './ng_control';
99
import {Control} from '../model';
10-
import {setUpControl} from './shared';
10+
import {NgValidator} from './validators';
11+
import {setUpControl, composeNgValidator} from './shared';
1112

1213
const formControlBinding = CONST_EXPR(new Binding(NgControl, {toAlias: forwardRef(() => NgModel)}));
1314

@@ -42,13 +43,20 @@ export class NgModel extends NgControl {
4243
_added = false;
4344
ngModel = new EventEmitter();
4445
model: any;
46+
ngValidators: QueryList<NgValidator>;
47+
48+
// Scope the query once https://github.com/angular/angular/issues/2603 is fixed
49+
constructor(@Query(NgValidator) ngValidators: QueryList<NgValidator>) {
50+
super();
51+
this.ngValidators = ngValidators;
52+
}
4553

4654
onChange(c) {
4755
if (!this._added) {
4856
setUpControl(this._control, this);
49-
this.control.updateValidity();
57+
this._control.updateValidity();
5058
this._added = true;
51-
};
59+
}
5260

5361
if (StringMapWrapper.contains(c, "model")) {
5462
this._control.updateValue(this.model);
@@ -59,5 +67,7 @@ export class NgModel extends NgControl {
5967

6068
get path(): List<string> { return []; }
6169

70+
get validator(): Function { return composeNgValidator(this.ngValidators); }
71+
6272
viewToModelUpdate(newValue: any): void { ObservableWrapper.callNext(this.ngModel, newValue); }
6373
}

modules/angular2/src/forms/directives/shared.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import {ListWrapper} from 'angular2/src/facade/collection';
1+
import {ListWrapper, iterableToList} from 'angular2/src/facade/collection';
22
import {isBlank, BaseException} from 'angular2/src/facade/lang';
33

44
import {ControlContainer} from './control_container';
55
import {NgControl} from './ng_control';
6+
import {NgValidator} from './validators';
67
import {Control} from '../model';
78
import {Validators} from '../validators';
8-
import {Renderer, ElementRef} from 'angular2/angular2';
9+
import {Renderer, ElementRef, QueryList} from 'angular2/angular2';
910

1011

1112
export function controlPath(name, parent: ControlContainer) {
@@ -35,6 +36,11 @@ export function setUpControl(c: Control, dir: NgControl) {
3536
dir.valueAccessor.registerOnTouched(() => c.markAsTouched());
3637
}
3738

39+
export function composeNgValidator(ngValidators: QueryList<NgValidator>): Function {
40+
if (isBlank(ngValidators)) return Validators.nullValidator;
41+
return Validators.compose(iterableToList(ngValidators).map(v => v.validator));
42+
}
43+
3844
function _throwError(dir: NgControl, message: string): void {
3945
var path = ListWrapper.join(dir.path, " -> ");
4046
throw new BaseException(`${message} '${path}'`);
@@ -43,5 +49,5 @@ function _throwError(dir: NgControl, message: string): void {
4349
export function setProperty(renderer: Renderer, elementRef: ElementRef, propName: string,
4450
propValue: any) {
4551
renderer.setElementProperty(elementRef.parentView.render, elementRef.boundElementIndex, propName,
46-
propValue);
52+
propValue);
4753
}
Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1+
import {forwardRef, Binding} from 'angular2/di';
2+
import {CONST_EXPR} from 'angular2/src/facade/lang';
13
import {Directive} from '../../../angular2';
24
import {Validators} from '../validators';
3-
import {NgControl} from '../directives';
45

5-
@Directive({selector: '[required][ng-control],[required][ng-form-control],[required][ng-model]'})
6-
export class NgRequiredValidator {
7-
constructor(c: NgControl) {
8-
c.validator = Validators.compose([c.validator, Validators.required]);
9-
}
6+
export class NgValidator {
7+
get validator(): Function { throw "Is not implemented"; }
8+
}
9+
10+
const requiredValidatorBinding =
11+
CONST_EXPR(new Binding(NgValidator, {toAlias: forwardRef(() => NgRequiredValidator)}));
12+
13+
@Directive({
14+
selector: '[required][ng-control],[required][ng-form-control],[required][ng-model]',
15+
hostInjector: [requiredValidatorBinding]
16+
})
17+
export class NgRequiredValidator extends NgValidator {
18+
get validator(): Function { return Validators.required; }
1019
}

0 commit comments

Comments
 (0)