From c9fba3fa1f96a762d9ac43dfba0b40c9f9c4ed71 Mon Sep 17 00:00:00 2001 From: Ted Sander Date: Fri, 16 Oct 2015 12:04:33 -0700 Subject: [PATCH] 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) --- modules/angular2/src/core/forms/model.ts | 16 ++++++++++++++++ modules/angular2/test/core/forms/model_spec.ts | 18 ++++++++++++++++++ modules/angular2/test/public_api_spec.ts | 8 ++++++++ 3 files changed, 42 insertions(+) diff --git a/modules/angular2/src/core/forms/model.ts b/modules/angular2/src/core/forms/model.ts index fff05a0a33..ba006866fb 100644 --- a/modules/angular2/src/core/forms/model.ts +++ b/modules/angular2/src/core/forms/model.ts @@ -13,6 +13,12 @@ export const VALID = "VALID"; */ 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 { return control instanceof AbstractControl; } @@ -75,6 +81,7 @@ export class AbstractControl { get untouched(): boolean { return !this._touched; } get valueChanges(): Observable { return this._valueChanges; } + get pending(): boolean { return this._status == PENDING; } 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; } updateValidity({onlySelf}: {onlySelf?: boolean} = {}): void { diff --git a/modules/angular2/test/core/forms/model_spec.ts b/modules/angular2/test/core/forms/model_spec.ts index 39e857ad59..4dc90e5b07 100644 --- a/modules/angular2/test/core/forms/model_spec.ts +++ b/modules/angular2/test/core/forms/model_spec.ts @@ -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", () => { var a: ControlArray; var c1, c2; diff --git a/modules/angular2/test/public_api_spec.ts b/modules/angular2/test/public_api_spec.ts index dd39ee7a1d..af640687c5 100644 --- a/modules/angular2/test/public_api_spec.ts +++ b/modules/angular2/test/public_api_spec.ts @@ -47,7 +47,9 @@ var NG_API = [ 'AbstractControl.getError()', 'AbstractControl.hasError()', 'AbstractControl.markAsDirty()', + 'AbstractControl.markAsPending()', 'AbstractControl.markAsTouched()', + 'AbstractControl.pending', 'AbstractControl.pristine', 'AbstractControl.setParent()', 'AbstractControl.status', @@ -277,7 +279,9 @@ var NG_API = [ 'Control.getError()', 'Control.hasError()', 'Control.markAsDirty()', + 'Control.markAsPending()', 'Control.markAsTouched()', + 'Control.pending', 'Control.pristine', 'Control.registerOnChange()', 'Control.setParent()', @@ -304,7 +308,9 @@ var NG_API = [ 'ControlArray.insert()', 'ControlArray.length', 'ControlArray.markAsDirty()', + 'ControlArray.markAsPending()', 'ControlArray.markAsTouched()', + 'ControlArray.pending', 'ControlArray.pristine', 'ControlArray.push()', 'ControlArray.removeAt()', @@ -345,7 +351,9 @@ var NG_API = [ 'ControlGroup.hasError()', 'ControlGroup.include()', 'ControlGroup.markAsDirty()', + 'ControlGroup.markAsPending()', 'ControlGroup.markAsTouched()', + 'ControlGroup.pending', 'ControlGroup.pristine', 'ControlGroup.removeControl()', 'ControlGroup.setParent()',