diff --git a/modules/@angular/common/src/forms/form_builder.ts b/modules/@angular/common/src/forms/form_builder.ts index a4a8a0eb58..a5eceb2cf3 100644 --- a/modules/@angular/common/src/forms/form_builder.ts +++ b/modules/@angular/common/src/forms/form_builder.ts @@ -69,8 +69,9 @@ export class FormBuilder { /** * Construct a new {@link FormControl} with the given `value`,`validator`, and `asyncValidator`. */ - control(value: Object, validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null): - modelModule.FormControl { + control( + value: Object, validator: ValidatorFn|ValidatorFn[] = null, + asyncValidator: AsyncValidatorFn|AsyncValidatorFn[] = null): modelModule.FormControl { return new modelModule.FormControl(value, validator, asyncValidator); } diff --git a/modules/@angular/common/src/forms/model.ts b/modules/@angular/common/src/forms/model.ts index 6a93010409..618b3c945b 100644 --- a/modules/@angular/common/src/forms/model.ts +++ b/modules/@angular/common/src/forms/model.ts @@ -3,9 +3,11 @@ import {ListWrapper, StringMapWrapper} from '../facade/collection'; import {isBlank, isPresent, normalizeBool} from '../facade/lang'; import {PromiseWrapper} from '../facade/promise'; +import {composeAsyncValidators, composeValidators} from './directives/shared'; import {AsyncValidatorFn, ValidatorFn} from './directives/validators'; + /** * Indicates that a FormControl is valid, i.e. that no errors exist in the input value. */ @@ -50,6 +52,15 @@ function toObservable(r: any): Observable { return PromiseWrapper.isPromise(r) ? ObservableWrapper.fromPromise(r) : r; } +function coerceToValidator(validator: ValidatorFn | ValidatorFn[]): ValidatorFn { + return Array.isArray(validator) ? composeValidators(validator) : validator; +} + +function coerceToAsyncValidator(asyncValidator: AsyncValidatorFn | AsyncValidatorFn[]): + AsyncValidatorFn { + return Array.isArray(asyncValidator) ? composeAsyncValidators(asyncValidator) : asyncValidator; +} + /** * @experimental */ @@ -275,8 +286,9 @@ export class FormControl extends AbstractControl { _onChange: Function; constructor( - value: any = null, validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null) { - super(validator, asyncValidator); + value: any = null, validator: ValidatorFn|ValidatorFn[] = null, + asyncValidator: AsyncValidatorFn|AsyncValidatorFn[] = null) { + super(coerceToValidator(validator), coerceToAsyncValidator(asyncValidator)); this._value = value; this.updateValueAndValidity({onlySelf: true, emitEvent: false}); this._initObservables(); diff --git a/modules/@angular/common/test/forms/model_spec.ts b/modules/@angular/common/test/forms/model_spec.ts index 75d5e073ae..e645b2c428 100644 --- a/modules/@angular/common/test/forms/model_spec.ts +++ b/modules/@angular/common/test/forms/model_spec.ts @@ -31,6 +31,8 @@ export function main() { return e; } + function otherAsyncValidator() { return PromiseWrapper.resolve({'other': true}); } + describe('Form Model', () => { describe('FormControl', () => { it('should default the value to null', () => { @@ -50,6 +52,15 @@ export function main() { expect(c.valid).toEqual(false); }); + it('should support arrays of validator functions if passed', () => { + const c = new FormControl('value', [Validators.required, Validators.minLength(3)]); + c.updateValue('a'); + expect(c.valid).toEqual(false); + + c.updateValue('aaa'); + expect(c.valid).toEqual(true); + }); + it('should return errors', () => { var c = new FormControl(null, Validators.required); expect(c.errors).toEqual({'required': true}); @@ -116,6 +127,14 @@ export function main() { expect(c.valid).toEqual(true); })); + + it('should support arrays of async validator functions if passed', fakeAsync(() => { + const c = + new FormControl('value', null, [asyncValidator('expected'), otherAsyncValidator]); + tick(); + + expect(c.errors).toEqual({'async': true, 'other': true}); + })); }); describe('dirty', () => {