feat(forms): add support for adding async validators via template
Example: @Directive({ selector: '[uniq-login-validator]', providers: [provide(NG_ASYNC_VALIDATORS, {useExisting: UniqLoginValidator, multi: true})] }) class UniqLoginValidator implements Validator { validate(c) { return someFunctionReturningPromiseOrObservable(); } }
This commit is contained in:
parent
cf449ddaa9
commit
31c12af81f
|
@ -33,7 +33,7 @@ export {
|
||||||
SelectControlValueAccessor
|
SelectControlValueAccessor
|
||||||
} from './forms/directives/select_control_value_accessor';
|
} from './forms/directives/select_control_value_accessor';
|
||||||
export {FORM_DIRECTIVES} from './forms/directives';
|
export {FORM_DIRECTIVES} from './forms/directives';
|
||||||
export {NG_VALIDATORS, Validators} from './forms/validators';
|
export {NG_VALIDATORS, NG_ASYNC_VALIDATORS, Validators} from './forms/validators';
|
||||||
export {
|
export {
|
||||||
RequiredValidator,
|
RequiredValidator,
|
||||||
MinLengthValidator,
|
MinLengthValidator,
|
||||||
|
|
|
@ -13,6 +13,7 @@ export abstract class NgControl extends AbstractControlDirective {
|
||||||
valueAccessor: ControlValueAccessor = null;
|
valueAccessor: ControlValueAccessor = null;
|
||||||
|
|
||||||
get validator(): Function { return unimplemented(); }
|
get validator(): Function { return unimplemented(); }
|
||||||
|
get asyncValidator(): Function { return unimplemented(); }
|
||||||
|
|
||||||
abstract viewToModelUpdate(newValue: any): void;
|
abstract viewToModelUpdate(newValue: any): void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,10 @@ import {ListWrapper} from 'angular2/src/core/facade/collection';
|
||||||
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
|
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||||
|
|
||||||
import {ControlContainer} from './control_container';
|
import {ControlContainer} from './control_container';
|
||||||
import {controlPath} from './shared';
|
import {controlPath, composeValidators, composeAsyncValidators} from './shared';
|
||||||
import {ControlGroup} from '../model';
|
import {ControlGroup} from '../model';
|
||||||
import {Form} from './form_interface';
|
import {Form} from './form_interface';
|
||||||
import {Validators, NG_VALIDATORS} from '../validators';
|
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||||
|
|
||||||
const controlGroupProvider =
|
const controlGroupProvider =
|
||||||
CONST_EXPR(new Provider(ControlContainer, {useExisting: forwardRef(() => NgControlGroup)}));
|
CONST_EXPR(new Provider(ControlContainer, {useExisting: forwardRef(() => NgControlGroup)}));
|
||||||
|
@ -72,13 +72,11 @@ export class NgControlGroup extends ControlContainer implements OnInit,
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_parent: ControlContainer;
|
_parent: ControlContainer;
|
||||||
|
|
||||||
private _validators: Function[];
|
|
||||||
|
|
||||||
constructor(@Host() @SkipSelf() parent: ControlContainer,
|
constructor(@Host() @SkipSelf() parent: ControlContainer,
|
||||||
@Optional() @Inject(NG_VALIDATORS) validators: Function[]) {
|
@Optional() @Inject(NG_VALIDATORS) private _validators: any[],
|
||||||
|
@Optional() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
this._parent = parent;
|
this._parent = parent;
|
||||||
this._validators = validators;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onInit(): void { this.formDirective.addControlGroup(this); }
|
onInit(): void { this.formDirective.addControlGroup(this); }
|
||||||
|
@ -100,5 +98,7 @@ export class NgControlGroup extends ControlContainer implements OnInit,
|
||||||
*/
|
*/
|
||||||
get formDirective(): Form { return this._parent.formDirective; }
|
get formDirective(): Form { return this._parent.formDirective; }
|
||||||
|
|
||||||
get validator(): Function { return Validators.compose(this._validators); }
|
get validator(): Function { return composeValidators(this._validators); }
|
||||||
|
|
||||||
|
get asyncValidator(): Function { return composeAsyncValidators(this._asyncValidators); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,15 @@ import {forwardRef, Host, SkipSelf, Provider, Inject, Optional} from 'angular2/s
|
||||||
import {ControlContainer} from './control_container';
|
import {ControlContainer} from './control_container';
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {controlPath, composeValidators, isPropertyUpdated, selectValueAccessor} from './shared';
|
import {
|
||||||
|
controlPath,
|
||||||
|
composeValidators,
|
||||||
|
composeAsyncValidators,
|
||||||
|
isPropertyUpdated,
|
||||||
|
selectValueAccessor
|
||||||
|
} from './shared';
|
||||||
import {Control} from '../model';
|
import {Control} from '../model';
|
||||||
import {Validators, NG_VALIDATORS} from '../validators';
|
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||||
|
|
||||||
|
|
||||||
const controlNameBinding =
|
const controlNameBinding =
|
||||||
|
@ -81,21 +87,18 @@ const controlNameBinding =
|
||||||
export class NgControlName extends NgControl implements OnChanges,
|
export class NgControlName extends NgControl implements OnChanges,
|
||||||
OnDestroy {
|
OnDestroy {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_parent: ControlContainer;
|
|
||||||
update = new EventEmitter();
|
update = new EventEmitter();
|
||||||
model: any;
|
model: any;
|
||||||
viewModel: any;
|
viewModel: any;
|
||||||
private _validator: Function;
|
private _added = false;
|
||||||
/** @internal */
|
|
||||||
_added = false;
|
|
||||||
|
|
||||||
constructor(@Host() @SkipSelf() parent: ControlContainer,
|
constructor(@Host() @SkipSelf() private _parent: ControlContainer,
|
||||||
@Optional() @Inject(NG_VALIDATORS) validators:
|
@Optional() @Inject(NG_VALIDATORS) private _validators:
|
||||||
|
/* Array<Validator|Function> */ any[],
|
||||||
|
@Optional() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators:
|
||||||
/* Array<Validator|Function> */ any[],
|
/* Array<Validator|Function> */ any[],
|
||||||
@Optional() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[]) {
|
@Optional() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[]) {
|
||||||
super();
|
super();
|
||||||
this._parent = parent;
|
|
||||||
this._validator = composeValidators(validators);
|
|
||||||
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +124,9 @@ export class NgControlName extends NgControl implements OnChanges,
|
||||||
|
|
||||||
get formDirective(): any { return this._parent.formDirective; }
|
get formDirective(): any { return this._parent.formDirective; }
|
||||||
|
|
||||||
get validator(): Function { return this._validator; }
|
get validator(): Function { return composeValidators(this._validators); }
|
||||||
|
|
||||||
|
get asyncValidator(): Function { return composeAsyncValidators(this._asyncValidators); }
|
||||||
|
|
||||||
get control(): Control { return this.formDirective.getControl(this); }
|
get control(): Control { return this.formDirective.getControl(this); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,8 @@ import {Form} from './form_interface';
|
||||||
import {NgControlGroup} from './ng_control_group';
|
import {NgControlGroup} from './ng_control_group';
|
||||||
import {ControlContainer} from './control_container';
|
import {ControlContainer} from './control_container';
|
||||||
import {AbstractControl, ControlGroup, Control} from '../model';
|
import {AbstractControl, ControlGroup, Control} from '../model';
|
||||||
import {setUpControl, setUpControlGroup} from './shared';
|
import {setUpControl, setUpControlGroup, composeValidators, composeAsyncValidators} from './shared';
|
||||||
import {Validators, NG_VALIDATORS} from '../validators';
|
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||||
|
|
||||||
const formDirectiveProvider =
|
const formDirectiveProvider =
|
||||||
CONST_EXPR(new Provider(ControlContainer, {useExisting: forwardRef(() => NgForm)}));
|
CONST_EXPR(new Provider(ControlContainer, {useExisting: forwardRef(() => NgForm)}));
|
||||||
|
@ -91,9 +91,11 @@ export class NgForm extends ControlContainer implements Form {
|
||||||
form: ControlGroup;
|
form: ControlGroup;
|
||||||
ngSubmit = new EventEmitter();
|
ngSubmit = new EventEmitter();
|
||||||
|
|
||||||
constructor(@Optional() @Inject(NG_VALIDATORS) validators: Function[]) {
|
constructor(@Optional() @Inject(NG_VALIDATORS) validators: any[],
|
||||||
|
@Optional() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
this.form = new ControlGroup({}, null, Validators.compose(validators));
|
this.form = new ControlGroup({}, null, composeValidators(validators),
|
||||||
|
composeAsyncValidators(asyncValidators));
|
||||||
}
|
}
|
||||||
|
|
||||||
get formDirective(): Form { return this; }
|
get formDirective(): Form { return this; }
|
||||||
|
|
|
@ -7,9 +7,15 @@ import {Query, Directive} from 'angular2/src/core/metadata';
|
||||||
import {forwardRef, Provider, Inject, Optional} from 'angular2/src/core/di';
|
import {forwardRef, Provider, Inject, Optional} from 'angular2/src/core/di';
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
import {Control} from '../model';
|
import {Control} from '../model';
|
||||||
import {Validators, NG_VALIDATORS} from '../validators';
|
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {setUpControl, composeValidators, isPropertyUpdated, selectValueAccessor} from './shared';
|
import {
|
||||||
|
setUpControl,
|
||||||
|
composeValidators,
|
||||||
|
composeAsyncValidators,
|
||||||
|
isPropertyUpdated,
|
||||||
|
selectValueAccessor
|
||||||
|
} from './shared';
|
||||||
|
|
||||||
const formControlBinding =
|
const formControlBinding =
|
||||||
CONST_EXPR(new Provider(NgControl, {useExisting: forwardRef(() => NgFormControl)}));
|
CONST_EXPR(new Provider(NgControl, {useExisting: forwardRef(() => NgFormControl)}));
|
||||||
|
@ -73,13 +79,13 @@ export class NgFormControl extends NgControl implements OnChanges {
|
||||||
update = new EventEmitter();
|
update = new EventEmitter();
|
||||||
model: any;
|
model: any;
|
||||||
viewModel: any;
|
viewModel: any;
|
||||||
private _validator: Function;
|
|
||||||
|
|
||||||
constructor(@Optional() @Inject(NG_VALIDATORS) validators:
|
constructor(@Optional() @Inject(NG_VALIDATORS) private _validators:
|
||||||
|
/* Array<Validator|Function> */ any[],
|
||||||
|
@Optional() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators:
|
||||||
/* Array<Validator|Function> */ any[],
|
/* Array<Validator|Function> */ any[],
|
||||||
@Optional() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[]) {
|
@Optional() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[]) {
|
||||||
super();
|
super();
|
||||||
this._validator = composeValidators(validators);
|
|
||||||
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +102,9 @@ export class NgFormControl extends NgControl implements OnChanges {
|
||||||
|
|
||||||
get path(): string[] { return []; }
|
get path(): string[] { return []; }
|
||||||
|
|
||||||
get validator(): Function { return this._validator; }
|
get validator(): Function { return composeValidators(this._validators); }
|
||||||
|
|
||||||
|
get asyncValidator(): Function { return composeAsyncValidators(this._asyncValidators); }
|
||||||
|
|
||||||
get control(): Control { return this.form; }
|
get control(): Control { return this.form; }
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ import {NgControlGroup} from './ng_control_group';
|
||||||
import {ControlContainer} from './control_container';
|
import {ControlContainer} from './control_container';
|
||||||
import {Form} from './form_interface';
|
import {Form} from './form_interface';
|
||||||
import {Control, ControlGroup} from '../model';
|
import {Control, ControlGroup} from '../model';
|
||||||
import {setUpControl, setUpControlGroup} from './shared';
|
import {setUpControl, setUpControlGroup, composeValidators, composeAsyncValidators} from './shared';
|
||||||
import {Validators, NG_VALIDATORS} from '../validators';
|
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||||
|
|
||||||
const formDirectiveProvider =
|
const formDirectiveProvider =
|
||||||
CONST_EXPR(new Provider(ControlContainer, {useExisting: forwardRef(() => NgFormModel)}));
|
CONST_EXPR(new Provider(ControlContainer, {useExisting: forwardRef(() => NgFormModel)}));
|
||||||
|
@ -102,17 +102,21 @@ export class NgFormModel extends ControlContainer implements Form,
|
||||||
form: ControlGroup = null;
|
form: ControlGroup = null;
|
||||||
directives: NgControl[] = [];
|
directives: NgControl[] = [];
|
||||||
ngSubmit = new EventEmitter();
|
ngSubmit = new EventEmitter();
|
||||||
private _validators: Function[];
|
|
||||||
|
|
||||||
constructor(@Optional() @Inject(NG_VALIDATORS) validators: Function[]) {
|
constructor(@Optional() @Inject(NG_VALIDATORS) private _validators: any[],
|
||||||
|
@Optional() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
this._validators = validators;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onChanges(changes: {[key: string]: SimpleChange}): void {
|
onChanges(changes: {[key: string]: SimpleChange}): void {
|
||||||
if (StringMapWrapper.contains(changes, "form")) {
|
if (StringMapWrapper.contains(changes, "form")) {
|
||||||
var c = Validators.compose(this._validators);
|
var sync = composeValidators(this._validators);
|
||||||
this.form.validator = Validators.compose([this.form.validator, c]);
|
this.form.validator = Validators.compose([this.form.validator, sync]);
|
||||||
|
|
||||||
|
var async = composeAsyncValidators(this._asyncValidators);
|
||||||
|
this.form.asyncValidator = Validators.composeAsync([this.form.asyncValidator, async]);
|
||||||
|
|
||||||
|
this.form.updateValueAndValidity({onlySelf: true, emitEvent: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
this._updateDomValue();
|
this._updateDomValue();
|
||||||
|
|
|
@ -7,8 +7,14 @@ import {forwardRef, Provider, Inject, Optional} from 'angular2/src/core/di';
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
import {Control} from '../model';
|
import {Control} from '../model';
|
||||||
import {Validators, NG_VALIDATORS} from '../validators';
|
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||||
import {setUpControl, isPropertyUpdated, selectValueAccessor, composeValidators} from './shared';
|
import {
|
||||||
|
setUpControl,
|
||||||
|
isPropertyUpdated,
|
||||||
|
selectValueAccessor,
|
||||||
|
composeValidators,
|
||||||
|
composeAsyncValidators
|
||||||
|
} from './shared';
|
||||||
|
|
||||||
const formControlBinding =
|
const formControlBinding =
|
||||||
CONST_EXPR(new Provider(NgControl, {useExisting: forwardRef(() => NgModel)}));
|
CONST_EXPR(new Provider(NgControl, {useExisting: forwardRef(() => NgModel)}));
|
||||||
|
@ -49,13 +55,11 @@ export class NgModel extends NgControl implements OnChanges {
|
||||||
update = new EventEmitter();
|
update = new EventEmitter();
|
||||||
model: any;
|
model: any;
|
||||||
viewModel: any;
|
viewModel: any;
|
||||||
private _validator: Function;
|
|
||||||
|
|
||||||
constructor(@Optional() @Inject(NG_VALIDATORS) validators:
|
constructor(@Optional() @Inject(NG_VALIDATORS) private _validators: any[],
|
||||||
/* Array<Validator|Function> */ any[],
|
@Optional() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[],
|
||||||
@Optional() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[]) {
|
@Optional() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[]) {
|
||||||
super();
|
super();
|
||||||
this._validator = composeValidators(validators);
|
|
||||||
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
this.valueAccessor = selectValueAccessor(this, valueAccessors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +80,9 @@ export class NgModel extends NgControl implements OnChanges {
|
||||||
|
|
||||||
get path(): string[] { return []; }
|
get path(): string[] { return []; }
|
||||||
|
|
||||||
get validator(): Function { return this._validator; }
|
get validator(): Function { return composeValidators(this._validators); }
|
||||||
|
|
||||||
|
get asyncValidator(): Function { return composeAsyncValidators(this._asyncValidators); }
|
||||||
|
|
||||||
viewToModelUpdate(newValue: any): void {
|
viewToModelUpdate(newValue: any): void {
|
||||||
this.viewModel = newValue;
|
this.viewModel = newValue;
|
||||||
|
|
|
@ -29,6 +29,7 @@ export function setUpControl(control: Control, dir: NgControl): void {
|
||||||
if (isBlank(dir.valueAccessor)) _throwError(dir, "No value accessor for");
|
if (isBlank(dir.valueAccessor)) _throwError(dir, "No value accessor for");
|
||||||
|
|
||||||
control.validator = Validators.compose([control.validator, dir.validator]);
|
control.validator = Validators.compose([control.validator, dir.validator]);
|
||||||
|
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
||||||
dir.valueAccessor.writeValue(control.value);
|
dir.valueAccessor.writeValue(control.value);
|
||||||
|
|
||||||
// view -> model
|
// view -> model
|
||||||
|
@ -48,6 +49,7 @@ export function setUpControl(control: Control, dir: NgControl): void {
|
||||||
export function setUpControlGroup(control: ControlGroup, dir: NgControlGroup) {
|
export function setUpControlGroup(control: ControlGroup, dir: NgControlGroup) {
|
||||||
if (isBlank(control)) _throwError(dir, "Cannot find control");
|
if (isBlank(control)) _throwError(dir, "Cannot find control");
|
||||||
control.validator = Validators.compose([control.validator, dir.validator]);
|
control.validator = Validators.compose([control.validator, dir.validator]);
|
||||||
|
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _throwError(dir: AbstractControlDirective, message: string): void {
|
function _throwError(dir: AbstractControlDirective, message: string): void {
|
||||||
|
@ -61,8 +63,12 @@ export function setProperty(renderer: Renderer, elementRef: ElementRef, propName
|
||||||
}
|
}
|
||||||
|
|
||||||
export function composeValidators(validators: /* Array<Validator|Function> */ any[]): Function {
|
export function composeValidators(validators: /* Array<Validator|Function> */ any[]): Function {
|
||||||
return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) :
|
return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null;
|
||||||
Validators.nullValidator;
|
}
|
||||||
|
|
||||||
|
export function composeAsyncValidators(
|
||||||
|
validators: /* Array<Validator|Function> */ any[]): Function {
|
||||||
|
return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeValidator)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {
|
export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {
|
||||||
|
|
|
@ -142,8 +142,9 @@ export abstract class AbstractControl {
|
||||||
if (isPresent(this.asyncValidator)) {
|
if (isPresent(this.asyncValidator)) {
|
||||||
this._status = PENDING;
|
this._status = PENDING;
|
||||||
this._cancelExistingSubscription();
|
this._cancelExistingSubscription();
|
||||||
|
var obs = ObservableWrapper.fromPromise(this.asyncValidator(this));
|
||||||
this._asyncValidationSubscription =
|
this._asyncValidationSubscription =
|
||||||
ObservableWrapper.subscribe(this.asyncValidator(this), res => this.setErrors(res));
|
ObservableWrapper.subscribe(obs, res => this.setErrors(res));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,8 @@ import {
|
||||||
afterEach,
|
afterEach,
|
||||||
el,
|
el,
|
||||||
AsyncTestCompleter,
|
AsyncTestCompleter,
|
||||||
inject
|
inject,
|
||||||
|
tick
|
||||||
} from 'angular2/testing_internal';
|
} from 'angular2/testing_internal';
|
||||||
|
|
||||||
import {SpyNgControl, SpyValueAccessor} from '../spies';
|
import {SpyNgControl, SpyValueAccessor} from '../spies';
|
||||||
|
@ -38,7 +39,8 @@ import {
|
||||||
|
|
||||||
|
|
||||||
import {selectValueAccessor, composeValidators} from 'angular2/src/core/forms/directives/shared';
|
import {selectValueAccessor, composeValidators} from 'angular2/src/core/forms/directives/shared';
|
||||||
|
import {TimerWrapper} from 'angular2/src/core/facade/async';
|
||||||
|
import {PromiseWrapper} from 'angular2/src/core/facade/promise';
|
||||||
import {SimpleChange} from 'angular2/src/core/change_detection';
|
import {SimpleChange} from 'angular2/src/core/change_detection';
|
||||||
|
|
||||||
class DummyControlValueAccessor implements ControlValueAccessor {
|
class DummyControlValueAccessor implements ControlValueAccessor {
|
||||||
|
@ -54,6 +56,19 @@ class CustomValidatorDirective implements Validator {
|
||||||
validate(c: Control): {[key: string]: any} { return {"custom": true}; }
|
validate(c: Control): {[key: string]: any} { return {"custom": true}; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function asyncValidator(expected, timeout = 0) {
|
||||||
|
return (c) => {
|
||||||
|
var completer = PromiseWrapper.completer();
|
||||||
|
var res = c.value != expected ? {"async": true} : null;
|
||||||
|
if (timeout == 0) {
|
||||||
|
completer.resolve(res);
|
||||||
|
} else {
|
||||||
|
TimerWrapper.setTimeout(() => { completer.resolve(res); }, timeout);
|
||||||
|
}
|
||||||
|
return completer.promise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe("Form Directives", () => {
|
describe("Form Directives", () => {
|
||||||
var defaultAccessor;
|
var defaultAccessor;
|
||||||
|
@ -125,7 +140,7 @@ export function main() {
|
||||||
var loginControlDir;
|
var loginControlDir;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
form = new NgFormModel([]);
|
form = new NgFormModel([], []);
|
||||||
formModel = new ControlGroup({
|
formModel = new ControlGroup({
|
||||||
"login": new Control(),
|
"login": new Control(),
|
||||||
"passwords":
|
"passwords":
|
||||||
|
@ -133,7 +148,8 @@ export function main() {
|
||||||
});
|
});
|
||||||
form.form = formModel;
|
form.form = formModel;
|
||||||
|
|
||||||
loginControlDir = new NgControlName(form, [Validators.required], [defaultAccessor]);
|
loginControlDir = new NgControlName(form, [Validators.required],
|
||||||
|
[asyncValidator("expected")], [defaultAccessor]);
|
||||||
loginControlDir.name = "login";
|
loginControlDir.name = "login";
|
||||||
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
||||||
});
|
});
|
||||||
|
@ -151,7 +167,7 @@ export function main() {
|
||||||
|
|
||||||
describe("addControl", () => {
|
describe("addControl", () => {
|
||||||
it("should throw when no control found", () => {
|
it("should throw when no control found", () => {
|
||||||
var dir = new NgControlName(form, null, [defaultAccessor]);
|
var dir = new NgControlName(form, null, null, [defaultAccessor]);
|
||||||
dir.name = "invalidName";
|
dir.name = "invalidName";
|
||||||
|
|
||||||
expect(() => form.addControl(dir))
|
expect(() => form.addControl(dir))
|
||||||
|
@ -159,21 +175,30 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when no value accessor", () => {
|
it("should throw when no value accessor", () => {
|
||||||
var dir = new NgControlName(form, null, null);
|
var dir = new NgControlName(form, null, null, null);
|
||||||
dir.name = "login";
|
dir.name = "login";
|
||||||
|
|
||||||
expect(() => form.addControl(dir))
|
expect(() => form.addControl(dir))
|
||||||
.toThrowError(new RegExp("No value accessor for 'login'"));
|
.toThrowError(new RegExp("No value accessor for 'login'"));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up validator", () => {
|
it("should set up validators", fakeAsync(() => {
|
||||||
expect(formModel.find(["login"]).valid).toBe(true);
|
|
||||||
|
|
||||||
// this will add the required validator and recalculate the validity
|
|
||||||
form.addControl(loginControlDir);
|
form.addControl(loginControlDir);
|
||||||
|
|
||||||
expect(formModel.find(["login"]).valid).toBe(false);
|
// sync validators are set
|
||||||
});
|
expect(formModel.hasError("required", ["login"])).toBe(true);
|
||||||
|
expect(formModel.hasError("async", ["login"])).toBe(false);
|
||||||
|
|
||||||
|
formModel.find(["login"]).updateValue("invalid value");
|
||||||
|
|
||||||
|
// sync validator passes, running async validators
|
||||||
|
expect(formModel.pending).toBe(true);
|
||||||
|
|
||||||
|
tick();
|
||||||
|
|
||||||
|
expect(formModel.hasError("required", ["login"])).toBe(false);
|
||||||
|
expect(formModel.hasError("async", ["login"])).toBe(true);
|
||||||
|
}));
|
||||||
|
|
||||||
it("should write value to the DOM", () => {
|
it("should write value to the DOM", () => {
|
||||||
formModel.find(["login"]).updateValue("initValue");
|
formModel.find(["login"]).updateValue("initValue");
|
||||||
|
@ -198,15 +223,27 @@ export function main() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
it("should set up validator", () => {
|
it("should set up validator", fakeAsync(() => {
|
||||||
var group = new NgControlGroup(form, [matchingPasswordsValidator]);
|
var group = new NgControlGroup(form, [matchingPasswordsValidator],
|
||||||
|
[asyncValidator('expected')]);
|
||||||
group.name = "passwords";
|
group.name = "passwords";
|
||||||
form.addControlGroup(group);
|
form.addControlGroup(group);
|
||||||
|
|
||||||
formModel.find(["passwords", "password"]).updateValue("somePassword");
|
formModel.find(["passwords", "password"]).updateValue("somePassword");
|
||||||
|
formModel.find(["passwords", "passwordConfirm"]).updateValue("someOtherPassword");
|
||||||
|
|
||||||
|
// sync validators are set
|
||||||
expect(formModel.hasError("differentPasswords", ["passwords"])).toEqual(true);
|
expect(formModel.hasError("differentPasswords", ["passwords"])).toEqual(true);
|
||||||
});
|
|
||||||
|
formModel.find(["passwords", "passwordConfirm"]).updateValue("somePassword");
|
||||||
|
|
||||||
|
// sync validators pass, running async validators
|
||||||
|
expect(formModel.pending).toBe(true);
|
||||||
|
|
||||||
|
tick();
|
||||||
|
|
||||||
|
expect(formModel.hasError("async", ["passwords"])).toBe(true);
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("removeControl", () => {
|
describe("removeControl", () => {
|
||||||
|
@ -228,17 +265,24 @@ export function main() {
|
||||||
expect((<any>loginControlDir.valueAccessor).writtenValue).toEqual("new value");
|
expect((<any>loginControlDir.valueAccessor).writtenValue).toEqual("new value");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up validator", () => {
|
it("should set up a sync validator", () => {
|
||||||
var formValidator = (c) => ({"custom": true});
|
var formValidator = (c) => ({"custom": true});
|
||||||
var f = new NgFormModel([formValidator]);
|
var f = new NgFormModel([formValidator], []);
|
||||||
f.form = formModel;
|
f.form = formModel;
|
||||||
f.onChanges({"form": formModel});
|
f.onChanges({"form": formModel});
|
||||||
|
|
||||||
// trigger validation
|
|
||||||
formModel.controls["login"].updateValue("");
|
|
||||||
|
|
||||||
expect(formModel.errors).toEqual({"custom": true});
|
expect(formModel.errors).toEqual({"custom": true});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should set up an async validator", fakeAsync(() => {
|
||||||
|
var f = new NgFormModel([], [asyncValidator("expected")]);
|
||||||
|
f.form = formModel;
|
||||||
|
f.onChanges({"form": formModel});
|
||||||
|
|
||||||
|
tick();
|
||||||
|
|
||||||
|
expect(formModel.errors).toEqual({"async": true});
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -249,13 +293,13 @@ export function main() {
|
||||||
var personControlGroupDir;
|
var personControlGroupDir;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
form = new NgForm([]);
|
form = new NgForm([], []);
|
||||||
formModel = form.form;
|
formModel = form.form;
|
||||||
|
|
||||||
personControlGroupDir = new NgControlGroup(form, []);
|
personControlGroupDir = new NgControlGroup(form, [], []);
|
||||||
personControlGroupDir.name = "person";
|
personControlGroupDir.name = "person";
|
||||||
|
|
||||||
loginControlDir = new NgControlName(personControlGroupDir, null, [defaultAccessor]);
|
loginControlDir = new NgControlName(personControlGroupDir, null, null, [defaultAccessor]);
|
||||||
loginControlDir.name = "login";
|
loginControlDir.name = "login";
|
||||||
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
loginControlDir.valueAccessor = new DummyControlValueAccessor();
|
||||||
});
|
});
|
||||||
|
@ -301,16 +345,22 @@ export function main() {
|
||||||
// should update the form's value and validity
|
// should update the form's value and validity
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up validator", fakeAsync(() => {
|
it("should set up sync validator", fakeAsync(() => {
|
||||||
var formValidator = (c) => ({"custom": true});
|
var formValidator = (c) => ({"custom": true});
|
||||||
var f = new NgForm([formValidator]);
|
var f = new NgForm([formValidator], []);
|
||||||
f.addControlGroup(personControlGroupDir);
|
|
||||||
f.addControl(loginControlDir);
|
|
||||||
|
|
||||||
flushMicrotasks();
|
tick();
|
||||||
|
|
||||||
expect(f.form.errors).toEqual({"custom": true});
|
expect(f.form.errors).toEqual({"custom": true});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it("should set up async validator", fakeAsync(() => {
|
||||||
|
var f = new NgForm([], [asyncValidator("expected")]);
|
||||||
|
|
||||||
|
tick();
|
||||||
|
|
||||||
|
expect(f.form.errors).toEqual({"async": true});
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgControlGroup", () => {
|
describe("NgControlGroup", () => {
|
||||||
|
@ -320,9 +370,9 @@ export function main() {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
formModel = new ControlGroup({"login": new Control(null)});
|
formModel = new ControlGroup({"login": new Control(null)});
|
||||||
|
|
||||||
var parent = new NgFormModel([]);
|
var parent = new NgFormModel([], []);
|
||||||
parent.form = new ControlGroup({"group": formModel});
|
parent.form = new ControlGroup({"group": formModel});
|
||||||
controlGroupDir = new NgControlGroup(parent, []);
|
controlGroupDir = new NgControlGroup(parent, [], []);
|
||||||
controlGroupDir.name = "group";
|
controlGroupDir.name = "group";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -353,7 +403,7 @@ export function main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
controlDir = new NgFormControl([Validators.required], [defaultAccessor]);
|
controlDir = new NgFormControl([Validators.required], [], [defaultAccessor]);
|
||||||
controlDir.valueAccessor = new DummyControlValueAccessor();
|
controlDir.valueAccessor = new DummyControlValueAccessor();
|
||||||
|
|
||||||
control = new Control(null);
|
control = new Control(null);
|
||||||
|
@ -384,7 +434,8 @@ export function main() {
|
||||||
var ngModel;
|
var ngModel;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
ngModel = new NgModel([Validators.required], [defaultAccessor]);
|
ngModel =
|
||||||
|
new NgModel([Validators.required], [asyncValidator("expected")], [defaultAccessor]);
|
||||||
ngModel.valueAccessor = new DummyControlValueAccessor();
|
ngModel.valueAccessor = new DummyControlValueAccessor();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -400,14 +451,18 @@ export function main() {
|
||||||
expect(ngModel.untouched).toBe(control.untouched);
|
expect(ngModel.untouched).toBe(control.untouched);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set up validator", () => {
|
it("should set up validator", fakeAsync(() => {
|
||||||
expect(ngModel.control.valid).toBe(true);
|
|
||||||
|
|
||||||
// this will add the required validator and recalculate the validity
|
// this will add the required validator and recalculate the validity
|
||||||
ngModel.onChanges({});
|
ngModel.onChanges({});
|
||||||
|
tick();
|
||||||
|
|
||||||
expect(ngModel.control.valid).toBe(false);
|
expect(ngModel.control.errors).toEqual({"required": true});
|
||||||
});
|
|
||||||
|
ngModel.control.updateValue("someValue");
|
||||||
|
tick();
|
||||||
|
|
||||||
|
expect(ngModel.control.errors).toEqual({"async": true});
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("NgControlName", () => {
|
describe("NgControlName", () => {
|
||||||
|
@ -417,9 +472,9 @@ export function main() {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
formModel = new Control("name");
|
formModel = new Control("name");
|
||||||
|
|
||||||
var parent = new NgFormModel([]);
|
var parent = new NgFormModel([], []);
|
||||||
parent.form = new ControlGroup({"name": formModel});
|
parent.form = new ControlGroup({"name": formModel});
|
||||||
controlNameDir = new NgControlName(parent, [], [defaultAccessor]);
|
controlNameDir = new NgControlName(parent, [], [], [defaultAccessor]);
|
||||||
controlNameDir.name = "name";
|
controlNameDir.name = "name";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,13 @@ import {
|
||||||
|
|
||||||
import {DOM} from 'angular2/src/core/dom/dom_adapter';
|
import {DOM} from 'angular2/src/core/dom/dom_adapter';
|
||||||
import {
|
import {
|
||||||
|
Input,
|
||||||
Control,
|
Control,
|
||||||
ControlGroup,
|
ControlGroup,
|
||||||
ControlValueAccessor,
|
ControlValueAccessor,
|
||||||
FORM_DIRECTIVES,
|
FORM_DIRECTIVES,
|
||||||
NG_VALIDATORS,
|
NG_VALIDATORS,
|
||||||
|
NG_ASYNC_VALIDATORS,
|
||||||
Provider,
|
Provider,
|
||||||
NgControl,
|
NgControl,
|
||||||
NgIf,
|
NgIf,
|
||||||
|
@ -401,7 +403,7 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("validations", () => {
|
describe("validations", () => {
|
||||||
it("should use validators defined in html",
|
it("should use sync validators defined in html",
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
var form = new ControlGroup(
|
var form = new ControlGroup(
|
||||||
{"login": new Control(""), "min": new Control(""), "max": new Control("")});
|
{"login": new Control(""), "min": new Control(""), "max": new Control("")});
|
||||||
|
@ -446,6 +448,35 @@ export function main() {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it("should use async validators defined in the html",
|
||||||
|
inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => {
|
||||||
|
var form = new ControlGroup({"login": new Control("")});
|
||||||
|
|
||||||
|
var t = `<div [ng-form-model]="form">
|
||||||
|
<input type="text" ng-control="login" uniq-login-validator="expected">
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
var rootTC;
|
||||||
|
tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((root) => rootTC = root);
|
||||||
|
tick();
|
||||||
|
|
||||||
|
rootTC.debugElement.componentInstance.form = form;
|
||||||
|
rootTC.detectChanges();
|
||||||
|
|
||||||
|
expect(form.pending).toEqual(true);
|
||||||
|
|
||||||
|
tick(100);
|
||||||
|
|
||||||
|
expect(form.hasError("uniqLogin", ["login"])).toEqual(true);
|
||||||
|
|
||||||
|
var input = rootTC.debugElement.query(By.css("input"));
|
||||||
|
input.nativeElement.value = "expected";
|
||||||
|
dispatchEvent(input.nativeElement, "change");
|
||||||
|
tick(100);
|
||||||
|
|
||||||
|
expect(form.valid).toEqual(true);
|
||||||
|
})));
|
||||||
|
|
||||||
it("should use sync validators defined in the model",
|
it("should use sync validators defined in the model",
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
var form = new ControlGroup({"login": new Control("aa", Validators.required)});
|
var form = new ControlGroup({"login": new Control("aa", Validators.required)});
|
||||||
|
@ -961,10 +992,10 @@ class MyInput implements ControlValueAccessor {
|
||||||
|
|
||||||
function uniqLoginAsyncValidator(expectedValue: string) {
|
function uniqLoginAsyncValidator(expectedValue: string) {
|
||||||
return (c) => {
|
return (c) => {
|
||||||
var e = new EventEmitter();
|
var completer = PromiseWrapper.completer();
|
||||||
var res = (c.value == expectedValue) ? null : {"uniqLogin": true};
|
var res = (c.value == expectedValue) ? null : {"uniqLogin": true};
|
||||||
PromiseWrapper.scheduleMicrotask(() => ObservableWrapper.callNext(e, res));
|
completer.resolve(res);
|
||||||
return e;
|
return completer.promise;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,10 +1010,31 @@ function loginIsEmptyGroupValidator(c: ControlGroup) {
|
||||||
class LoginIsEmptyValidator {
|
class LoginIsEmptyValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[uniq-login-validator]',
|
||||||
|
providers: [
|
||||||
|
new Provider(NG_ASYNC_VALIDATORS,
|
||||||
|
{useExisting: forwardRef(() => UniqLoginValidator), multi: true})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
class UniqLoginValidator implements Validator {
|
||||||
|
@Input('uniq-login-validator') expected;
|
||||||
|
|
||||||
|
validate(c) { return uniqLoginAsyncValidator(this.expected)(c); }
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "my-comp",
|
selector: "my-comp",
|
||||||
template: '',
|
template: '',
|
||||||
directives: [FORM_DIRECTIVES, WrappedValue, MyInput, NgIf, NgFor, LoginIsEmptyValidator]
|
directives: [
|
||||||
|
FORM_DIRECTIVES,
|
||||||
|
WrappedValue,
|
||||||
|
MyInput,
|
||||||
|
NgIf,
|
||||||
|
NgFor,
|
||||||
|
LoginIsEmptyValidator,
|
||||||
|
UniqLoginValidator
|
||||||
|
]
|
||||||
})
|
})
|
||||||
class MyComp {
|
class MyComp {
|
||||||
form: any;
|
form: any;
|
||||||
|
|
|
@ -15,23 +15,24 @@ import {
|
||||||
} from 'angular2/testing_internal';
|
} from 'angular2/testing_internal';
|
||||||
import {ControlGroup, Control, ControlArray, Validators} from 'angular2/core';
|
import {ControlGroup, Control, ControlArray, Validators} from 'angular2/core';
|
||||||
import {isPresent, CONST_EXPR} from 'angular2/src/core/facade/lang';
|
import {isPresent, CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||||
import {EventEmitter, TimerWrapper, ObservableWrapper} from 'angular2/src/core/facade/async';
|
import {PromiseWrapper} from 'angular2/src/core/facade/promise';
|
||||||
|
import {TimerWrapper, ObservableWrapper} from 'angular2/src/core/facade/async';
|
||||||
import {IS_DART} from '../../platform';
|
import {IS_DART} from '../../platform';
|
||||||
import {PromiseWrapper} from "angular2/src/core/facade/promise";
|
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
function asyncValidator(expected, timeouts = CONST_EXPR({})) {
|
function asyncValidator(expected, timeouts = CONST_EXPR({})) {
|
||||||
return (c) => {
|
return (c) => {
|
||||||
var e = new EventEmitter();
|
var completer = PromiseWrapper.completer();
|
||||||
var t = isPresent(timeouts[c.value]) ? timeouts[c.value] : 0;
|
var t = isPresent(timeouts[c.value]) ? timeouts[c.value] : 0;
|
||||||
var res = c.value != expected ? {"async": true} : null;
|
var res = c.value != expected ? {"async": true} : null;
|
||||||
|
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
PromiseWrapper.scheduleMicrotask(() => { ObservableWrapper.callNext(e, res); });
|
completer.resolve(res);
|
||||||
} else {
|
} else {
|
||||||
TimerWrapper.setTimeout(() => { ObservableWrapper.callNext(e, res); }, t);
|
TimerWrapper.setTimeout(() => { completer.resolve(res); }, t);
|
||||||
}
|
}
|
||||||
return e;
|
|
||||||
|
return completer.promise;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -819,6 +819,7 @@ var NG_ALL = [
|
||||||
'LowerCasePipe',
|
'LowerCasePipe',
|
||||||
'LowerCasePipe.transform()',
|
'LowerCasePipe.transform()',
|
||||||
'NG_VALIDATORS',
|
'NG_VALIDATORS',
|
||||||
|
'NG_ASYNC_VALIDATORS',
|
||||||
'NgClass',
|
'NgClass',
|
||||||
'NgClass.doCheck()',
|
'NgClass.doCheck()',
|
||||||
'NgClass.initialClasses=',
|
'NgClass.initialClasses=',
|
||||||
|
@ -837,6 +838,7 @@ var NG_ALL = [
|
||||||
'NgControl.untouched',
|
'NgControl.untouched',
|
||||||
'NgControl.valid',
|
'NgControl.valid',
|
||||||
'NgControl.validator',
|
'NgControl.validator',
|
||||||
|
'NgControl.asyncValidator',
|
||||||
'NgControl.value',
|
'NgControl.value',
|
||||||
'NgControl.valueAccessor',
|
'NgControl.valueAccessor',
|
||||||
'NgControl.valueAccessor=',
|
'NgControl.valueAccessor=',
|
||||||
|
@ -857,6 +859,7 @@ var NG_ALL = [
|
||||||
'NgControlGroup.valid',
|
'NgControlGroup.valid',
|
||||||
'NgControlGroup.value',
|
'NgControlGroup.value',
|
||||||
'NgControlGroup.validator',
|
'NgControlGroup.validator',
|
||||||
|
'NgControlGroup.asyncValidator',
|
||||||
'NgControlStatus',
|
'NgControlStatus',
|
||||||
'NgControlStatus.ngClassDirty',
|
'NgControlStatus.ngClassDirty',
|
||||||
'NgControlStatus.ngClassInvalid',
|
'NgControlStatus.ngClassInvalid',
|
||||||
|
@ -884,6 +887,7 @@ var NG_ALL = [
|
||||||
'NgControlName.update=',
|
'NgControlName.update=',
|
||||||
'NgControlName.valid',
|
'NgControlName.valid',
|
||||||
'NgControlName.validator',
|
'NgControlName.validator',
|
||||||
|
'NgControlName.asyncValidator',
|
||||||
'NgControlName.value',
|
'NgControlName.value',
|
||||||
'NgControlName.valueAccessor',
|
'NgControlName.valueAccessor',
|
||||||
'NgControlName.valueAccessor=',
|
'NgControlName.valueAccessor=',
|
||||||
|
@ -941,6 +945,7 @@ var NG_ALL = [
|
||||||
'NgFormControl.update=',
|
'NgFormControl.update=',
|
||||||
'NgFormControl.valid',
|
'NgFormControl.valid',
|
||||||
'NgFormControl.validator',
|
'NgFormControl.validator',
|
||||||
|
'NgFormControl.asyncValidator',
|
||||||
'NgFormControl.value',
|
'NgFormControl.value',
|
||||||
'NgFormControl.valueAccessor',
|
'NgFormControl.valueAccessor',
|
||||||
'NgFormControl.valueAccessor=',
|
'NgFormControl.valueAccessor=',
|
||||||
|
@ -996,6 +1001,7 @@ var NG_ALL = [
|
||||||
'NgModel.update=',
|
'NgModel.update=',
|
||||||
'NgModel.valid',
|
'NgModel.valid',
|
||||||
'NgModel.validator',
|
'NgModel.validator',
|
||||||
|
'NgModel.asyncValidator',
|
||||||
'NgModel.value',
|
'NgModel.value',
|
||||||
'NgModel.valueAccessor',
|
'NgModel.valueAccessor',
|
||||||
'NgModel.valueAccessor=',
|
'NgModel.valueAccessor=',
|
||||||
|
@ -1223,6 +1229,7 @@ var NG_ALL = [
|
||||||
'UrlResolver',
|
'UrlResolver',
|
||||||
'UrlResolver.resolve()',
|
'UrlResolver.resolve()',
|
||||||
'Validators#compose()',
|
'Validators#compose()',
|
||||||
|
'Validators#composeAsync()',
|
||||||
'Validators#nullValidator()',
|
'Validators#nullValidator()',
|
||||||
'Validators#required()',
|
'Validators#required()',
|
||||||
'Validators#minLength()',
|
'Validators#minLength()',
|
||||||
|
|
Loading…
Reference in New Issue