feat(validators): Add a pending state to AbstractControl

Add a pending state to AbstractControl and a function to set that state on
themselves and their parents. This will be used for both individual async
validators and when the imperitive mode is used. [Design Doc](https://docs.google.com/document/d/1EnJ3-_iFpVKFz1ifN1LkXSGQ7h3A72OQGry2g8eo7IA/edit?pli=1#heading=h.j53rt81eegm4)
This commit is contained in:
Ted Sander 2015-10-16 12:04:33 -07:00 committed by vsavkin
parent 04b4035ecd
commit c9fba3fa1f
3 changed files with 42 additions and 0 deletions

View File

@ -13,6 +13,12 @@ export const VALID = "VALID";
*/ */
export const INVALID = "INVALID"; export const INVALID = "INVALID";
/**
* Indicates that a Control is pending, i.e. that async validation is occuring and
* errors are not yet available for the input value.
*/
export const PENDING = "PENDING";
export function isControl(control: Object): boolean { export function isControl(control: Object): boolean {
return control instanceof AbstractControl; return control instanceof AbstractControl;
} }
@ -75,6 +81,7 @@ export class AbstractControl {
get untouched(): boolean { return !this._touched; } get untouched(): boolean { return !this._touched; }
get valueChanges(): Observable { return this._valueChanges; } get valueChanges(): Observable { return this._valueChanges; }
get pending(): boolean { return this._status == PENDING; }
markAsTouched(): void { this._touched = true; } markAsTouched(): void { this._touched = true; }
@ -87,6 +94,15 @@ export class AbstractControl {
} }
} }
markAsPending({onlySelf}: {onlySelf?: boolean} = {}): void {
onlySelf = normalizeBool(onlySelf);
this._status = PENDING;
if (isPresent(this._parent) && !onlySelf) {
this._parent.markAsPending({onlySelf: onlySelf});
}
}
setParent(parent: ControlGroup | ControlArray): void { this._parent = parent; } setParent(parent: ControlGroup | ControlArray): void { this._parent = parent; }
updateValidity({onlySelf}: {onlySelf?: boolean} = {}): void { updateValidity({onlySelf}: {onlySelf?: boolean} = {}): void {

View File

@ -479,6 +479,24 @@ export function main() {
}); });
}); });
describe("pending", () => {
var c: Control;
var a: ControlArray;
beforeEach(() => {
c = new Control('value');
a = new ControlArray([c]);
});
it("should be false after creating a control", () => { expect(a.pending).toEqual(false); });
it("should be false after changing the value of the control", () => {
c.markAsPending();
expect(a.pending).toEqual(true);
});
});
describe("valueChanges", () => { describe("valueChanges", () => {
var a: ControlArray; var a: ControlArray;
var c1, c2; var c1, c2;

View File

@ -47,7 +47,9 @@ var NG_API = [
'AbstractControl.getError()', 'AbstractControl.getError()',
'AbstractControl.hasError()', 'AbstractControl.hasError()',
'AbstractControl.markAsDirty()', 'AbstractControl.markAsDirty()',
'AbstractControl.markAsPending()',
'AbstractControl.markAsTouched()', 'AbstractControl.markAsTouched()',
'AbstractControl.pending',
'AbstractControl.pristine', 'AbstractControl.pristine',
'AbstractControl.setParent()', 'AbstractControl.setParent()',
'AbstractControl.status', 'AbstractControl.status',
@ -277,7 +279,9 @@ var NG_API = [
'Control.getError()', 'Control.getError()',
'Control.hasError()', 'Control.hasError()',
'Control.markAsDirty()', 'Control.markAsDirty()',
'Control.markAsPending()',
'Control.markAsTouched()', 'Control.markAsTouched()',
'Control.pending',
'Control.pristine', 'Control.pristine',
'Control.registerOnChange()', 'Control.registerOnChange()',
'Control.setParent()', 'Control.setParent()',
@ -304,7 +308,9 @@ var NG_API = [
'ControlArray.insert()', 'ControlArray.insert()',
'ControlArray.length', 'ControlArray.length',
'ControlArray.markAsDirty()', 'ControlArray.markAsDirty()',
'ControlArray.markAsPending()',
'ControlArray.markAsTouched()', 'ControlArray.markAsTouched()',
'ControlArray.pending',
'ControlArray.pristine', 'ControlArray.pristine',
'ControlArray.push()', 'ControlArray.push()',
'ControlArray.removeAt()', 'ControlArray.removeAt()',
@ -345,7 +351,9 @@ var NG_API = [
'ControlGroup.hasError()', 'ControlGroup.hasError()',
'ControlGroup.include()', 'ControlGroup.include()',
'ControlGroup.markAsDirty()', 'ControlGroup.markAsDirty()',
'ControlGroup.markAsPending()',
'ControlGroup.markAsTouched()', 'ControlGroup.markAsTouched()',
'ControlGroup.pending',
'ControlGroup.pristine', 'ControlGroup.pristine',
'ControlGroup.removeControl()', 'ControlGroup.removeControl()',
'ControlGroup.setParent()', 'ControlGroup.setParent()',