committed by
Miško Hevery
parent
ef9e40e82b
commit
14f0e9ada8
@@ -1,6 +1,7 @@
|
||||
import {ControlValueAccessor} from './control_value_accessor';
|
||||
import {AbstractControlDirective} from './abstract_control_directive';
|
||||
import {unimplemented} from 'angular2/src/facade/exceptions';
|
||||
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||
|
||||
/**
|
||||
* A base class that all control directive extend.
|
||||
@@ -12,8 +13,8 @@ export abstract class NgControl extends AbstractControlDirective {
|
||||
name: string = null;
|
||||
valueAccessor: ControlValueAccessor = null;
|
||||
|
||||
get validator(): Function { return unimplemented(); }
|
||||
get asyncValidator(): Function { return unimplemented(); }
|
||||
get validator(): ValidatorFn { return <ValidatorFn>unimplemented(); }
|
||||
get asyncValidator(): AsyncValidatorFn { return <AsyncValidatorFn>unimplemented(); }
|
||||
|
||||
abstract viewToModelUpdate(newValue: any): void;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ import {ControlContainer} from './control_container';
|
||||
import {controlPath, composeValidators, composeAsyncValidators} from './shared';
|
||||
import {ControlGroup} from '../model';
|
||||
import {Form} from './form_interface';
|
||||
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||
|
||||
const controlGroupProvider =
|
||||
CONST_EXPR(new Provider(ControlContainer, {useExisting: forwardRef(() => NgControlGroup)}));
|
||||
@@ -106,7 +107,7 @@ export class NgControlGroup extends ControlContainer implements OnInit,
|
||||
*/
|
||||
get formDirective(): Form { return this._parent.formDirective; }
|
||||
|
||||
get validator(): Function { return composeValidators(this._validators); }
|
||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||
|
||||
get asyncValidator(): Function { return composeAsyncValidators(this._asyncValidators); }
|
||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ import {
|
||||
selectValueAccessor
|
||||
} from './shared';
|
||||
import {Control} from '../model';
|
||||
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
||||
|
||||
|
||||
const controlNameBinding =
|
||||
@@ -136,9 +137,9 @@ export class NgControlName extends NgControl implements OnChanges,
|
||||
|
||||
get formDirective(): any { return this._parent.formDirective; }
|
||||
|
||||
get validator(): Function { return composeValidators(this._validators); }
|
||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||
|
||||
get asyncValidator(): Function { return composeAsyncValidators(this._asyncValidators); }
|
||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
||||
|
||||
get control(): Control { return this.formDirective.getControl(this); }
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
isPropertyUpdated,
|
||||
selectValueAccessor
|
||||
} from './shared';
|
||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
||||
|
||||
const formControlBinding =
|
||||
CONST_EXPR(new Provider(NgControl, {useExisting: forwardRef(() => NgFormControl)}));
|
||||
@@ -110,9 +111,9 @@ export class NgFormControl extends NgControl implements OnChanges {
|
||||
|
||||
get path(): string[] { return []; }
|
||||
|
||||
get validator(): Function { return composeValidators(this._validators); }
|
||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||
|
||||
get asyncValidator(): Function { return composeAsyncValidators(this._asyncValidators); }
|
||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
||||
|
||||
get control(): Control { return this.form; }
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||
import {
|
||||
OnChanges,
|
||||
SimpleChange,
|
||||
Query,
|
||||
Directive,
|
||||
forwardRef,
|
||||
Provider,
|
||||
@@ -14,7 +13,7 @@ import {
|
||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||
import {NgControl} from './ng_control';
|
||||
import {Control} from '../model';
|
||||
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||
import {
|
||||
setUpControl,
|
||||
isPropertyUpdated,
|
||||
@@ -22,6 +21,7 @@ import {
|
||||
composeValidators,
|
||||
composeAsyncValidators
|
||||
} from './shared';
|
||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
||||
|
||||
const formControlBinding =
|
||||
CONST_EXPR(new Provider(NgControl, {useExisting: forwardRef(() => NgModel)}));
|
||||
@@ -88,9 +88,9 @@ export class NgModel extends NgControl implements OnChanges {
|
||||
|
||||
get path(): string[] { return []; }
|
||||
|
||||
get validator(): Function { return composeValidators(this._validators); }
|
||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||
|
||||
get asyncValidator(): Function { return composeAsyncValidators(this._asyncValidators); }
|
||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
||||
|
||||
viewToModelUpdate(newValue: any): void {
|
||||
this.viewModel = newValue;
|
||||
|
||||
@@ -10,3 +10,11 @@ Function normalizeValidator(dynamic validator){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Function normalizeAsyncValidator(dynamic validator){
|
||||
if (validator is Validator) {
|
||||
return (c) => validator.validate(c);
|
||||
} else {
|
||||
return validator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import {Validator} from './validators';
|
||||
import {Control} from "../model";
|
||||
import {AbstractControl} from "../model";
|
||||
import {Validator, ValidatorFn, AsyncValidatorFn} from './validators';
|
||||
|
||||
export type ctrlFunc = ((c: Control) => {
|
||||
[key: string]: any
|
||||
});
|
||||
|
||||
export function normalizeValidator(validator: (ctrlFunc | Validator)): ctrlFunc {
|
||||
export function normalizeValidator(validator: ValidatorFn | Validator): ValidatorFn {
|
||||
if ((<Validator>validator).validate !== undefined) {
|
||||
return (c: Control) => (<Validator>validator).validate(c);
|
||||
return (c: AbstractControl) => (<Validator>validator).validate(c);
|
||||
} else {
|
||||
return <ctrlFunc>validator;
|
||||
return <ValidatorFn>validator;
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeAsyncValidator(validator: AsyncValidatorFn | Validator): AsyncValidatorFn {
|
||||
if ((<Validator>validator).validate !== undefined) {
|
||||
return (c: AbstractControl) => Promise.resolve((<Validator>validator).validate(c));
|
||||
} else {
|
||||
return <AsyncValidatorFn>validator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ import {NumberValueAccessor} from './number_value_accessor';
|
||||
import {CheckboxControlValueAccessor} from './checkbox_value_accessor';
|
||||
import {SelectControlValueAccessor} from './select_control_value_accessor';
|
||||
import {RadioControlValueAccessor} from './radio_control_value_accessor';
|
||||
import {normalizeValidator} from './normalize_validator';
|
||||
import {normalizeValidator, normalizeAsyncValidator} from './normalize_validator';
|
||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
||||
|
||||
|
||||
export function controlPath(name: string, parent: ControlContainer): string[] {
|
||||
@@ -56,13 +57,14 @@ function _throwError(dir: AbstractControlDirective, message: string): void {
|
||||
throw new BaseException(`${message} '${path}'`);
|
||||
}
|
||||
|
||||
export function composeValidators(validators: /* Array<Validator|Function> */ any[]): Function {
|
||||
export function composeValidators(validators: /* Array<Validator|Function> */ any[]): ValidatorFn {
|
||||
return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null;
|
||||
}
|
||||
|
||||
export function composeAsyncValidators(
|
||||
validators: /* Array<Validator|Function> */ any[]): Function {
|
||||
return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeValidator)) : null;
|
||||
validators: /* Array<Validator|Function> */ any[]): AsyncValidatorFn {
|
||||
return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
|
||||
null;
|
||||
}
|
||||
|
||||
export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import {forwardRef, Provider, OpaqueToken, Attribute, Directive} from 'angular2/core';
|
||||
import {forwardRef, Provider, Attribute, Directive} from 'angular2/core';
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {Validators, NG_VALIDATORS} from '../validators';
|
||||
import {Control} from '../model';
|
||||
import {AbstractControl} from '../model';
|
||||
import * as modelModule from '../model';
|
||||
import {NumberWrapper} from "angular2/src/facade/lang";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An interface that can be implemented by classes that can act as validators.
|
||||
*
|
||||
@@ -23,7 +24,7 @@ import {NumberWrapper} from "angular2/src/facade/lang";
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface Validator { validate(c: modelModule.Control): {[key: string]: any}; }
|
||||
export interface Validator { validate(c: modelModule.AbstractControl): {[key: string]: any}; }
|
||||
|
||||
const REQUIRED_VALIDATOR =
|
||||
CONST_EXPR(new Provider(NG_VALIDATORS, {useValue: Validators.required, multi: true}));
|
||||
@@ -45,6 +46,11 @@ const REQUIRED_VALIDATOR =
|
||||
export class RequiredValidator {
|
||||
}
|
||||
|
||||
export interface ValidatorFn { (c: AbstractControl): {[key: string]: any}; }
|
||||
export interface AsyncValidatorFn {
|
||||
(c: AbstractControl): any /*Promise<{[key: string]: any}>|Observable<{[key: string]: any}>*/;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provivder which adds {@link MinLengthValidator} to {@link NG_VALIDATORS}.
|
||||
*
|
||||
@@ -64,13 +70,13 @@ const MIN_LENGTH_VALIDATOR = CONST_EXPR(
|
||||
providers: [MIN_LENGTH_VALIDATOR]
|
||||
})
|
||||
export class MinLengthValidator implements Validator {
|
||||
private _validator: Function;
|
||||
private _validator: ValidatorFn;
|
||||
|
||||
constructor(@Attribute("minlength") minLength: string) {
|
||||
this._validator = Validators.minLength(NumberWrapper.parseInt(minLength, 10));
|
||||
}
|
||||
|
||||
validate(c: Control): {[key: string]: any} { return this._validator(c); }
|
||||
validate(c: AbstractControl): {[key: string]: any} { return this._validator(c); }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,13 +98,13 @@ const MAX_LENGTH_VALIDATOR = CONST_EXPR(
|
||||
providers: [MAX_LENGTH_VALIDATOR]
|
||||
})
|
||||
export class MaxLengthValidator implements Validator {
|
||||
private _validator: Function;
|
||||
private _validator: ValidatorFn;
|
||||
|
||||
constructor(@Attribute("maxlength") maxLength: string) {
|
||||
this._validator = Validators.maxLength(NumberWrapper.parseInt(maxLength, 10));
|
||||
}
|
||||
|
||||
validate(c: Control): {[key: string]: any} { return this._validator(c); }
|
||||
validate(c: AbstractControl): {[key: string]: any} { return this._validator(c); }
|
||||
}
|
||||
|
||||
|
||||
@@ -121,11 +127,11 @@ const PATTERN_VALIDATOR = CONST_EXPR(
|
||||
providers: [PATTERN_VALIDATOR]
|
||||
})
|
||||
export class PatternValidator implements Validator {
|
||||
private _validator: Function;
|
||||
private _validator: ValidatorFn;
|
||||
|
||||
constructor(@Attribute("pattern") pattern: string) {
|
||||
this._validator = Validators.pattern(pattern);
|
||||
}
|
||||
|
||||
validate(c: Control): {[key: string]: any} { return this._validator(c); }
|
||||
validate(c: AbstractControl): {[key: string]: any} { return this._validator(c); }
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import {Injectable} from 'angular2/core';
|
||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {isPresent, isArray, CONST_EXPR, Type} from 'angular2/src/facade/lang';
|
||||
import * as modelModule from './model';
|
||||
import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
||||
|
||||
|
||||
/**
|
||||
@@ -56,16 +57,18 @@ export class FormBuilder {
|
||||
group(controlsConfig: {[key: string]: any},
|
||||
extra: {[key: string]: any} = null): modelModule.ControlGroup {
|
||||
var controls = this._reduceControls(controlsConfig);
|
||||
var optionals = isPresent(extra) ? StringMapWrapper.get(extra, "optionals") : null;
|
||||
var validator = isPresent(extra) ? StringMapWrapper.get(extra, "validator") : null;
|
||||
var asyncValidator = isPresent(extra) ? StringMapWrapper.get(extra, "asyncValidator") : null;
|
||||
var optionals = <{[key: string]: boolean}>(
|
||||
isPresent(extra) ? StringMapWrapper.get(extra, "optionals") : null);
|
||||
var validator: ValidatorFn = isPresent(extra) ? StringMapWrapper.get(extra, "validator") : null;
|
||||
var asyncValidator: AsyncValidatorFn =
|
||||
isPresent(extra) ? StringMapWrapper.get(extra, "asyncValidator") : null;
|
||||
return new modelModule.ControlGroup(controls, optionals, validator, asyncValidator);
|
||||
}
|
||||
/**
|
||||
* Construct a new {@link Control} with the given `value`,`validator`, and `asyncValidator`.
|
||||
*/
|
||||
control(value: Object, validator: Function = null,
|
||||
asyncValidator: Function = null): modelModule.Control {
|
||||
control(value: Object, validator: ValidatorFn = null,
|
||||
asyncValidator: AsyncValidatorFn = null): modelModule.Control {
|
||||
return new modelModule.Control(value, validator, asyncValidator);
|
||||
}
|
||||
|
||||
@@ -73,8 +76,8 @@ export class FormBuilder {
|
||||
* Construct an array of {@link Control}s from the given `controlsConfig` array of
|
||||
* configuration, with the given optional `validator` and `asyncValidator`.
|
||||
*/
|
||||
array(controlsConfig: any[], validator: Function = null,
|
||||
asyncValidator: Function = null): modelModule.ControlArray {
|
||||
array(controlsConfig: any[], validator: ValidatorFn = null,
|
||||
asyncValidator: AsyncValidatorFn = null): modelModule.ControlArray {
|
||||
var controls = controlsConfig.map(c => this._createControl(c));
|
||||
return new modelModule.ControlArray(controls, validator, asyncValidator);
|
||||
}
|
||||
@@ -98,12 +101,12 @@ export class FormBuilder {
|
||||
|
||||
} else if (isArray(controlConfig)) {
|
||||
var value = controlConfig[0];
|
||||
var validator = controlConfig.length > 1 ? controlConfig[1] : null;
|
||||
var asyncValidator = controlConfig.length > 2 ? controlConfig[2] : null;
|
||||
var validator: ValidatorFn = controlConfig.length > 1 ? controlConfig[1] : null;
|
||||
var asyncValidator: AsyncValidatorFn = controlConfig.length > 2 ? controlConfig[2] : null;
|
||||
return this.control(value, validator, asyncValidator);
|
||||
|
||||
} else {
|
||||
return this.control(controlConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import {StringWrapper, isPresent, isBlank, normalizeBool} from 'angular2/src/facade/lang';
|
||||
import {isPresent, isBlank, normalizeBool} from 'angular2/src/facade/lang';
|
||||
import {Observable, EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/promise';
|
||||
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
||||
|
||||
/**
|
||||
* Indicates that a Control is valid, i.e. that no errors exist in the input value.
|
||||
@@ -64,7 +65,7 @@ export abstract class AbstractControl {
|
||||
private _parent: ControlGroup | ControlArray;
|
||||
private _asyncValidationSubscription: any;
|
||||
|
||||
constructor(public validator: Function, public asyncValidator: Function) {}
|
||||
constructor(public validator: ValidatorFn, public asyncValidator: AsyncValidatorFn) {}
|
||||
|
||||
get value(): any { return this._value; }
|
||||
|
||||
@@ -137,15 +138,17 @@ export abstract class AbstractControl {
|
||||
}
|
||||
}
|
||||
|
||||
private _runValidator() { return isPresent(this.validator) ? this.validator(this) : null; }
|
||||
private _runValidator(): {[key: string]: any} {
|
||||
return isPresent(this.validator) ? this.validator(this) : null;
|
||||
}
|
||||
|
||||
private _runAsyncValidator(emitEvent: boolean): void {
|
||||
if (isPresent(this.asyncValidator)) {
|
||||
this._status = PENDING;
|
||||
this._cancelExistingSubscription();
|
||||
var obs = toObservable(this.asyncValidator(this));
|
||||
this._asyncValidationSubscription =
|
||||
ObservableWrapper.subscribe(obs, res => this.setErrors(res, {emitEvent: emitEvent}));
|
||||
this._asyncValidationSubscription = ObservableWrapper.subscribe(
|
||||
obs, (res: {[key: string]: any}) => this.setErrors(res, {emitEvent: emitEvent}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +271,8 @@ export class Control extends AbstractControl {
|
||||
/** @internal */
|
||||
_onChange: Function;
|
||||
|
||||
constructor(value: any = null, validator: Function = null, asyncValidator: Function = null) {
|
||||
constructor(value: any = null, validator: ValidatorFn = null,
|
||||
asyncValidator: AsyncValidatorFn = null) {
|
||||
super(validator, asyncValidator);
|
||||
this._value = value;
|
||||
this.updateValueAndValidity({onlySelf: true, emitEvent: false});
|
||||
@@ -331,8 +335,8 @@ export class ControlGroup extends AbstractControl {
|
||||
private _optionals: {[key: string]: boolean};
|
||||
|
||||
constructor(public controls: {[key: string]: AbstractControl},
|
||||
optionals: {[key: string]: boolean} = null, validator: Function = null,
|
||||
asyncValidator: Function = null) {
|
||||
optionals: {[key: string]: boolean} = null, validator: ValidatorFn = null,
|
||||
asyncValidator: AsyncValidatorFn = null) {
|
||||
super(validator, asyncValidator);
|
||||
this._optionals = isPresent(optionals) ? optionals : {};
|
||||
this._initObservables();
|
||||
@@ -444,8 +448,8 @@ export class ControlGroup extends AbstractControl {
|
||||
* ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
|
||||
*/
|
||||
export class ControlArray extends AbstractControl {
|
||||
constructor(public controls: AbstractControl[], validator: Function = null,
|
||||
asyncValidator: Function = null) {
|
||||
constructor(public controls: AbstractControl[], validator: ValidatorFn = null,
|
||||
asyncValidator: AsyncValidatorFn = null) {
|
||||
super(validator, asyncValidator);
|
||||
this._initObservables();
|
||||
this._setParentForControls();
|
||||
|
||||
@@ -5,6 +5,7 @@ import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {OpaqueToken} from 'angular2/core';
|
||||
|
||||
import * as modelModule from './model';
|
||||
import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
||||
|
||||
/**
|
||||
* Providers for validators to be used for {@link Control}s in a form.
|
||||
@@ -43,7 +44,7 @@ export class Validators {
|
||||
/**
|
||||
* Validator that requires controls to have a non-empty value.
|
||||
*/
|
||||
static required(control: modelModule.Control): {[key: string]: boolean} {
|
||||
static required(control: modelModule.AbstractControl): {[key: string]: boolean} {
|
||||
return isBlank(control.value) || (isString(control.value) && control.value == "") ?
|
||||
{"required": true} :
|
||||
null;
|
||||
@@ -52,8 +53,8 @@ export class Validators {
|
||||
/**
|
||||
* Validator that requires controls to have a value of a minimum length.
|
||||
*/
|
||||
static minLength(minLength: number): Function {
|
||||
return (control: modelModule.Control): {[key: string]: any} => {
|
||||
static minLength(minLength: number): ValidatorFn {
|
||||
return (control: modelModule.AbstractControl): {[key: string]: any} => {
|
||||
if (isPresent(Validators.required(control))) return null;
|
||||
var v: string = control.value;
|
||||
return v.length < minLength ?
|
||||
@@ -65,8 +66,8 @@ export class Validators {
|
||||
/**
|
||||
* Validator that requires controls to have a value of a maximum length.
|
||||
*/
|
||||
static maxLength(maxLength: number): Function {
|
||||
return (control: modelModule.Control): {[key: string]: any} => {
|
||||
static maxLength(maxLength: number): ValidatorFn {
|
||||
return (control: modelModule.AbstractControl): {[key: string]: any} => {
|
||||
if (isPresent(Validators.required(control))) return null;
|
||||
var v: string = control.value;
|
||||
return v.length > maxLength ?
|
||||
@@ -78,8 +79,8 @@ export class Validators {
|
||||
/**
|
||||
* Validator that requires a control to match a regex to its value.
|
||||
*/
|
||||
static pattern(pattern: string): Function {
|
||||
return (control: modelModule.Control): {[key: string]: any} => {
|
||||
static pattern(pattern: string): ValidatorFn {
|
||||
return (control: modelModule.AbstractControl): {[key: string]: any} => {
|
||||
if (isPresent(Validators.required(control))) return null;
|
||||
let regex = new RegExp(`^${pattern}$`);
|
||||
let v: string = control.value;
|
||||
@@ -91,13 +92,13 @@ export class Validators {
|
||||
/**
|
||||
* No-op validator.
|
||||
*/
|
||||
static nullValidator(c: any): {[key: string]: boolean} { return null; }
|
||||
static nullValidator(c: modelModule.AbstractControl): {[key: string]: boolean} { return null; }
|
||||
|
||||
/**
|
||||
* Compose multiple validators into a single function that returns the union
|
||||
* of the individual error maps.
|
||||
*/
|
||||
static compose(validators: Function[]): Function {
|
||||
static compose(validators: ValidatorFn[]): ValidatorFn {
|
||||
if (isBlank(validators)) return null;
|
||||
var presentValidators = validators.filter(isPresent);
|
||||
if (presentValidators.length == 0) return null;
|
||||
@@ -107,13 +108,13 @@ export class Validators {
|
||||
};
|
||||
}
|
||||
|
||||
static composeAsync(validators: Function[]): Function {
|
||||
static composeAsync(validators: AsyncValidatorFn[]): AsyncValidatorFn {
|
||||
if (isBlank(validators)) return null;
|
||||
var presentValidators = validators.filter(isPresent);
|
||||
if (presentValidators.length == 0) return null;
|
||||
|
||||
return function(control: modelModule.AbstractControl) {
|
||||
let promises = _executeValidators(control, presentValidators).map(_convertToPromise);
|
||||
let promises = _executeAsyncValidators(control, presentValidators).map(_convertToPromise);
|
||||
return PromiseWrapper.all(promises).then(_mergeErrors);
|
||||
};
|
||||
}
|
||||
@@ -123,13 +124,20 @@ function _convertToPromise(obj: any): any {
|
||||
return PromiseWrapper.isPromise(obj) ? obj : ObservableWrapper.toPromise(obj);
|
||||
}
|
||||
|
||||
function _executeValidators(control: modelModule.AbstractControl, validators: Function[]): any[] {
|
||||
function _executeValidators(control: modelModule.AbstractControl,
|
||||
validators: ValidatorFn[]): any[] {
|
||||
return validators.map(v => v(control));
|
||||
}
|
||||
|
||||
function _executeAsyncValidators(control: modelModule.AbstractControl,
|
||||
validators: AsyncValidatorFn[]): any[] {
|
||||
return validators.map(v => v(control));
|
||||
}
|
||||
|
||||
function _mergeErrors(arrayOfErrors: any[]): {[key: string]: any} {
|
||||
var res = arrayOfErrors.reduce((res, errors) => {
|
||||
return isPresent(errors) ? StringMapWrapper.merge(<any>res, <any>errors) : res;
|
||||
}, {});
|
||||
var res: {[key: string]: any} =
|
||||
arrayOfErrors.reduce((res: {[key: string]: any}, errors: {[key: string]: any}) => {
|
||||
return isPresent(errors) ? StringMapWrapper.merge(res, errors) : res;
|
||||
}, {});
|
||||
return StringMapWrapper.isEmpty(res) ? null : res;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user