feat(forms): Implement a way to manually set errors on a control
Example:
var login = new Control("someLogin");
c.setErrors({"notUnique": true});
expect(c.valid).toEqual(false);
expect(c.errors).toEqual({"notUnique": true});
c.updateValue("newLogin");
expect(c.valid).toEqual(true);
BREAKING CHANGE:
Before:
ControlGroup.errors and ControlArray.errors returned a reduced value of their children controls' errors.
After:
ControlGroup.errors and ControlArray.errors return the errors of the group and array.
And ControlGroup.controlsErrors and ControlArray.controlsErrors return the reduce value of their children controls' errors.
Closes #4917
			
			
This commit is contained in:
		
							parent
							
								
									689ded5c47
								
							
						
					
					
						commit
						ed4826b08c
					
				| @ -12,6 +12,8 @@ export class AbstractControlDirective { | ||||
|     return isPresent(this.control) ? this.control.errors : null; | ||||
|   } | ||||
| 
 | ||||
|   get controlsErrors(): any { return isPresent(this.control) ? this.control.controlsErrors : null; } | ||||
| 
 | ||||
|   get pristine(): boolean { return isPresent(this.control) ? this.control.pristine : null; } | ||||
| 
 | ||||
|   get dirty(): boolean { return isPresent(this.control) ? this.control.dirty : null; } | ||||
|  | ||||
| @ -104,7 +104,7 @@ export class NgForm extends ControlContainer implements Form { | ||||
|       var ctrl = new Control(); | ||||
|       setUpControl(ctrl, dir); | ||||
|       container.addControl(dir.name, ctrl); | ||||
|       ctrl.updateValidity(); | ||||
|       ctrl.updateValueAndValidity({emitEvent: false}); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| @ -115,7 +115,7 @@ export class NgForm extends ControlContainer implements Form { | ||||
|       var container = this._findContainer(dir.path); | ||||
|       if (isPresent(container)) { | ||||
|         container.removeControl(dir.name); | ||||
|         container.updateValidity(); | ||||
|         container.updateValueAndValidity({emitEvent: false}); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| @ -125,7 +125,7 @@ export class NgForm extends ControlContainer implements Form { | ||||
|       var container = this._findContainer(dir.path); | ||||
|       var group = new ControlGroup({}); | ||||
|       container.addControl(dir.name, group); | ||||
|       group.updateValidity(); | ||||
|       group.updateValueAndValidity({emitEvent: false}); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| @ -134,7 +134,7 @@ export class NgForm extends ControlContainer implements Form { | ||||
|       var container = this._findContainer(dir.path); | ||||
|       if (isPresent(container)) { | ||||
|         container.removeControl(dir.name); | ||||
|         container.updateValidity(); | ||||
|         container.updateValueAndValidity({emitEvent: false}); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
| @ -85,7 +85,7 @@ export class NgFormControl extends NgControl implements OnChanges { | ||||
|   onChanges(changes: {[key: string]: SimpleChange}): void { | ||||
|     if (this._isControlChanged(changes)) { | ||||
|       setUpControl(this.form, this); | ||||
|       this.form.updateValidity(); | ||||
|       this.form.updateValueAndValidity({emitEvent: false}); | ||||
|     } | ||||
|     if (isPropertyUpdated(changes, this.viewModel)) { | ||||
|       this.form.updateValue(this.model); | ||||
|  | ||||
| @ -112,7 +112,7 @@ export class NgFormModel extends ControlContainer implements Form, | ||||
|   addControl(dir: NgControl): void { | ||||
|     var ctrl: any = this.form.find(dir.path); | ||||
|     setUpControl(ctrl, dir); | ||||
|     ctrl.updateValidity(); | ||||
|     ctrl.updateValueAndValidity({emitEvent: false}); | ||||
|     this.directives.push(dir); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -61,7 +61,7 @@ export class NgModel extends NgControl implements OnChanges { | ||||
|   onChanges(changes: {[key: string]: SimpleChange}) { | ||||
|     if (!this._added) { | ||||
|       setUpControl(this._control, this); | ||||
|       this._control.updateValidity(); | ||||
|       this._control.updateValueAndValidity({emitEvent: false}); | ||||
|       this._added = true; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -46,22 +46,20 @@ function _find(control: AbstractControl, path: Array<string | number>| string) { | ||||
| /** | ||||
|  * | ||||
|  */ | ||||
| export class AbstractControl { | ||||
| export abstract class AbstractControl { | ||||
|   /** @internal */ | ||||
|   _value: any; | ||||
|   /** @internal */ | ||||
|   _status: string; | ||||
|   /** @internal */ | ||||
|   _errors: {[key: string]: any}; | ||||
|   /** @internal */ | ||||
|   _pristine: boolean = true; | ||||
|   /** @internal */ | ||||
|   _touched: boolean = false; | ||||
|   /** @internal */ | ||||
|   _parent: ControlGroup | ControlArray; | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   _valueChanges: EventEmitter; | ||||
| 
 | ||||
|   private _status: string; | ||||
|   private _errors: {[key: string]: any}; | ||||
|   private _controlsErrors: any; | ||||
|   private _pristine: boolean = true; | ||||
|   private _touched: boolean = false; | ||||
|   private _parent: ControlGroup | ControlArray; | ||||
| 
 | ||||
|   constructor(public validator: Function) {} | ||||
| 
 | ||||
|   get value(): any { return this._value; } | ||||
| @ -70,8 +68,16 @@ export class AbstractControl { | ||||
| 
 | ||||
|   get valid(): boolean { return this._status === VALID; } | ||||
| 
 | ||||
|   /** | ||||
|    * Returns the errors of this control. | ||||
|    */ | ||||
|   get errors(): {[key: string]: any} { return this._errors; } | ||||
| 
 | ||||
|   /** | ||||
|    * Returns the errors of the child controls. | ||||
|    */ | ||||
|   get controlsErrors(): any { return this._controlsErrors; } | ||||
| 
 | ||||
|   get pristine(): boolean { return this._pristine; } | ||||
| 
 | ||||
|   get dirty(): boolean { return !this.pristine; } | ||||
| @ -105,17 +111,6 @@ export class AbstractControl { | ||||
| 
 | ||||
|   setParent(parent: ControlGroup | ControlArray): void { this._parent = parent; } | ||||
| 
 | ||||
|   updateValidity({onlySelf}: {onlySelf?: boolean} = {}): void { | ||||
|     onlySelf = normalizeBool(onlySelf); | ||||
| 
 | ||||
|     this._errors = this.validator(this); | ||||
|     this._status = isPresent(this._errors) ? INVALID : VALID; | ||||
| 
 | ||||
|     if (isPresent(this._parent) && !onlySelf) { | ||||
|       this._parent.updateValidity({onlySelf: onlySelf}); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   updateValueAndValidity({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): | ||||
|       void { | ||||
|     onlySelf = normalizeBool(onlySelf); | ||||
| @ -124,7 +119,8 @@ export class AbstractControl { | ||||
|     this._updateValue(); | ||||
| 
 | ||||
|     this._errors = this.validator(this); | ||||
|     this._status = isPresent(this._errors) ? INVALID : VALID; | ||||
|     this._controlsErrors = this._calculateControlsErrors(); | ||||
|     this._status = this._calculateStatus(); | ||||
| 
 | ||||
|     if (emitEvent) { | ||||
|       ObservableWrapper.callNext(this._valueChanges, this._value); | ||||
| @ -135,6 +131,38 @@ export class AbstractControl { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Sets errors on a control. | ||||
|    * | ||||
|    * This is used when validations are run not automatically, but manually by the user. | ||||
|    * | ||||
|    * Calling `setErrors` will also update the validity of the parent control. | ||||
|    * | ||||
|    * ## Usage | ||||
|    * | ||||
|    * ``` | ||||
|    * var login = new Control("someLogin"); | ||||
|    * login.setErrors({ | ||||
|    *   "notUnique": true | ||||
|    * }); | ||||
|    * | ||||
|    * expect(login.valid).toEqual(false); | ||||
|    * expect(login.errors).toEqual({"notUnique": true}); | ||||
|    * | ||||
|    * login.updateValue("someOtherLogin"); | ||||
|    * | ||||
|    * expect(login.valid).toEqual(true); | ||||
|    * ``` | ||||
|    */ | ||||
|   setErrors(errors: {[key: string]: any}): void { | ||||
|     this._errors = errors; | ||||
|     this._status = this._calculateStatus(); | ||||
| 
 | ||||
|     if (isPresent(this._parent)) { | ||||
|       this._parent._updateControlsErrors(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   find(path: Array<string | number>| string): AbstractControl { return _find(this, path); } | ||||
| 
 | ||||
|   getError(errorCode: string, path: string[] = null): any { | ||||
| @ -151,7 +179,23 @@ export class AbstractControl { | ||||
|   } | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   _updateValue(): void {} | ||||
|   _updateControlsErrors(): void { | ||||
|     this._controlsErrors = this._calculateControlsErrors(); | ||||
|     this._status = this._calculateStatus(); | ||||
| 
 | ||||
|     if (isPresent(this._parent)) { | ||||
|       this._parent._updateControlsErrors(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   private _calculateStatus(): string { | ||||
|     return isPresent(this._errors) || isPresent(this._controlsErrors) ? INVALID : VALID; | ||||
|   } | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   abstract _updateValue(): void; | ||||
|   /** @internal */ | ||||
|   abstract _calculateControlsErrors(): any; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -177,7 +221,7 @@ export class Control extends AbstractControl { | ||||
|   constructor(value: any = null, validator: Function = Validators.nullValidator) { | ||||
|     super(validator); | ||||
|     this._value = value; | ||||
|     this.updateValidity({onlySelf: true}); | ||||
|     this.updateValueAndValidity({onlySelf: true, emitEvent: false}); | ||||
|     this._valueChanges = new EventEmitter(); | ||||
|   } | ||||
| 
 | ||||
| @ -203,6 +247,16 @@ export class Control extends AbstractControl { | ||||
|     this.updateValueAndValidity({onlySelf: onlySelf, emitEvent: emitEvent}); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * @internal | ||||
|    */ | ||||
|   _updateValue() {} | ||||
| 
 | ||||
|   /** | ||||
|    * @internal | ||||
|    */ | ||||
|   _calculateControlsErrors() { return null; } | ||||
| 
 | ||||
|   /** | ||||
|    * Register a listener for change events. | ||||
|    */ | ||||
| @ -226,14 +280,14 @@ export class ControlGroup extends AbstractControl { | ||||
|   private _optionals: {[key: string]: boolean}; | ||||
| 
 | ||||
|   constructor(public controls: {[key: string]: AbstractControl}, | ||||
|               optionals: {[key: string]: boolean} = null, validator: Function = Validators.group) { | ||||
|               optionals: {[key: string]: boolean} = null, | ||||
|               validator: Function = Validators.nullValidator) { | ||||
|     super(validator); | ||||
|     this._optionals = isPresent(optionals) ? optionals : {}; | ||||
|     this._valueChanges = new EventEmitter(); | ||||
| 
 | ||||
|     this._setParentForControls(); | ||||
|     this._value = this._reduceValue(); | ||||
|     this.updateValidity({onlySelf: true}); | ||||
|     this.updateValueAndValidity({onlySelf: true, emitEvent: false}); | ||||
|   } | ||||
| 
 | ||||
|   addControl(name: string, control: AbstractControl): void { | ||||
| @ -266,6 +320,9 @@ export class ControlGroup extends AbstractControl { | ||||
|   /** @internal */ | ||||
|   _updateValue() { this._value = this._reduceValue(); } | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   _calculateControlsErrors() { return Validators.group(this); } | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   _reduceValue() { | ||||
|     return this._reduceChildren({}, (acc, control, name) => { | ||||
| @ -314,14 +371,13 @@ 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 = Validators.array) { | ||||
|   constructor(public controls: AbstractControl[], validator: Function = Validators.nullValidator) { | ||||
|     super(validator); | ||||
| 
 | ||||
|     this._valueChanges = new EventEmitter(); | ||||
| 
 | ||||
|     this._setParentForControls(); | ||||
|     this._updateValue(); | ||||
|     this.updateValidity({onlySelf: true}); | ||||
|     this.updateValueAndValidity({onlySelf: true, emitEvent: false}); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -363,6 +419,9 @@ export class ControlArray extends AbstractControl { | ||||
|   /** @internal */ | ||||
|   _updateValue(): void { this._value = this.controls.map((control) => control.value); } | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   _calculateControlsErrors() { return Validators.array(this); } | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   _setParentForControls(): void { | ||||
|     this.controls.forEach((control) => { control.setParent(this); }); | ||||
|  | ||||
| @ -62,10 +62,10 @@ export class Validators { | ||||
|         res[name] = control.errors; | ||||
|       } | ||||
|     }); | ||||
|     return StringMapWrapper.isEmpty(res) ? null : {'controls': res}; | ||||
|     return StringMapWrapper.isEmpty(res) ? null : res; | ||||
|   } | ||||
| 
 | ||||
|   static array(array: modelModule.ControlArray): {[key: string]: any} { | ||||
|   static array(array: modelModule.ControlArray): any[] { | ||||
|     var res: any[] = []; | ||||
|     var anyErrors: boolean = false; | ||||
|     array.controls.forEach((control) => { | ||||
| @ -74,6 +74,6 @@ export class Validators { | ||||
|         anyErrors = true; | ||||
|       } | ||||
|     }); | ||||
|     return anyErrors ? {'controls': res} : null; | ||||
|     return anyErrors ? res : null; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -53,7 +53,7 @@ export function main() { | ||||
|     it("should use default validators when no validators are provided", () => { | ||||
|       var g = b.group({"login": "some value"}); | ||||
|       expect(g.controls["login"].validator).toBe(Validators.nullValidator); | ||||
|       expect(g.validator).toBe(Validators.group); | ||||
|       expect(g.validator).toBe(Validators.nullValidator); | ||||
|     }); | ||||
| 
 | ||||
|     it("should create control arrays", () => { | ||||
|  | ||||
| @ -151,6 +151,61 @@ export function main() { | ||||
|              c.updateValue("new"); | ||||
|            })); | ||||
|       }); | ||||
| 
 | ||||
|       describe("setErrors", () => { | ||||
|         it("should set errors on a control", () => { | ||||
|           var c = new Control("someValue", Validators.nullValidator); | ||||
| 
 | ||||
|           c.setErrors({"someError": true}); | ||||
| 
 | ||||
|           expect(c.valid).toEqual(false); | ||||
|           expect(c.errors).toEqual({"someError": true}); | ||||
|         }); | ||||
| 
 | ||||
|         it("should reset the errors and validity when the value changes", () => { | ||||
|           var c = new Control("someValue", Validators.required); | ||||
| 
 | ||||
|           c.setErrors({"someError": true}); | ||||
|           c.updateValue(""); | ||||
| 
 | ||||
|           expect(c.errors).toEqual({"required": true}); | ||||
|         }); | ||||
| 
 | ||||
|         it("should update the parent group's validity", () => { | ||||
|           var c = new Control("someValue"); | ||||
|           var g = new ControlGroup({"one": c}); | ||||
| 
 | ||||
|           expect(g.valid).toEqual(true); | ||||
| 
 | ||||
|           c.setErrors({"someError": true}); | ||||
| 
 | ||||
|           expect(g.controlsErrors).toEqual({"one": {"someError": true}}); | ||||
|           expect(g.valid).toEqual(false); | ||||
|         }); | ||||
| 
 | ||||
|         it("should not reset parent's errors", () => { | ||||
|           var c = new Control("someValue"); | ||||
|           var g = new ControlGroup({"one": c}); | ||||
| 
 | ||||
|           g.setErrors({"someGroupError": true}); | ||||
|           c.setErrors({"someError": true}); | ||||
| 
 | ||||
|           expect(g.errors).toEqual({"someGroupError": true}); | ||||
|         }); | ||||
| 
 | ||||
|         it("update a value should reset errosr", () => { | ||||
|           var c = new Control("oldValue"); | ||||
|           var g = new ControlGroup({"one": c}); | ||||
| 
 | ||||
|           g.setErrors({"someGroupError": true}); | ||||
|           c.setErrors({"someError": true}); | ||||
| 
 | ||||
|           c.updateValue("newValue"); | ||||
| 
 | ||||
|           expect(c.errors).toEqual(null); | ||||
|           expect(g.errors).toEqual(null); | ||||
|         }); | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|     describe("ControlGroup", () => { | ||||
| @ -176,14 +231,12 @@ export function main() { | ||||
|         }); | ||||
|       }); | ||||
| 
 | ||||
| 
 | ||||
|       describe("validator", () => { | ||||
|       describe("controlsErrors", () => { | ||||
|         it("should run the validator with the initial value (valid)", () => { | ||||
|           var g = new ControlGroup({"one": new Control('value', Validators.required)}); | ||||
| 
 | ||||
|           expect(g.valid).toEqual(true); | ||||
| 
 | ||||
|           expect(g.errors).toEqual(null); | ||||
|           expect(g.controlsErrors).toEqual(null); | ||||
|         }); | ||||
| 
 | ||||
|         it("should run the validator with the initial value (invalid)", () => { | ||||
| @ -191,8 +244,7 @@ export function main() { | ||||
|           var g = new ControlGroup({"one": one}); | ||||
| 
 | ||||
|           expect(g.valid).toEqual(false); | ||||
| 
 | ||||
|           expect(g.errors).toEqual({"controls": {"one": {"required": true}}}); | ||||
|           expect(g.controlsErrors).toEqual({"one": {"required": true}}); | ||||
|         }); | ||||
| 
 | ||||
|         it("should run the validator with the value changes", () => { | ||||
| @ -201,8 +253,28 @@ export function main() { | ||||
| 
 | ||||
|           c.updateValue("some value"); | ||||
| 
 | ||||
|           expect(g.valid).toEqual(true); | ||||
|           expect(g.controlsErrors).toEqual(null); | ||||
|         }); | ||||
|       }); | ||||
| 
 | ||||
|       describe("errors", () => { | ||||
|         it("should run the validator when the value changes", () => { | ||||
|           var simpleValidator = (c) => | ||||
|               c.controls["one"].value != "correct" ? {"broken": true} : null; | ||||
| 
 | ||||
|           var c = new Control(null); | ||||
|           var g = new ControlGroup({"one": c}, null, simpleValidator); | ||||
| 
 | ||||
|           c.updateValue("correct"); | ||||
| 
 | ||||
|           expect(g.valid).toEqual(true); | ||||
|           expect(g.errors).toEqual(null); | ||||
| 
 | ||||
|           c.updateValue("incorrect"); | ||||
| 
 | ||||
|           expect(g.valid).toEqual(false); | ||||
|           expect(g.errors).toEqual({"broken": true}); | ||||
|         }); | ||||
|       }); | ||||
| 
 | ||||
| @ -278,6 +350,7 @@ export function main() { | ||||
| 
 | ||||
|           expect(group.valid).toEqual(false); | ||||
|         }); | ||||
|       }); | ||||
| 
 | ||||
|       describe("valueChanges", () => { | ||||
|         var g, c1, c2; | ||||
| @ -376,7 +449,6 @@ export function main() { | ||||
|         }); | ||||
|       }); | ||||
|     }); | ||||
|     }); | ||||
| 
 | ||||
|     describe("ControlArray", () => { | ||||
|       describe("adding/removing", () => { | ||||
| @ -428,13 +500,13 @@ export function main() { | ||||
|         }); | ||||
|       }); | ||||
| 
 | ||||
|       describe("validator", () => { | ||||
|       describe("controlsErrors", () => { | ||||
|         it("should run the validator with the initial value (valid)", () => { | ||||
|           var a = new ControlArray( | ||||
|               [new Control(1, Validators.required), new Control(2, Validators.required)]); | ||||
| 
 | ||||
|           expect(a.valid).toBe(true); | ||||
|           expect(a.errors).toBe(null); | ||||
|           expect(a.controlsErrors).toBe(null); | ||||
|         }); | ||||
| 
 | ||||
|         it("should run the validator with the initial value (invalid)", () => { | ||||
| @ -445,7 +517,7 @@ export function main() { | ||||
|           ]); | ||||
| 
 | ||||
|           expect(a.valid).toBe(false); | ||||
|           expect(a.errors).toEqual({"controls": [null, {"required": true}, null]}); | ||||
|           expect(a.controlsErrors).toEqual([null, {"required": true}, null]); | ||||
|         }); | ||||
| 
 | ||||
|         it("should run the validator when the value changes", () => { | ||||
| @ -457,10 +529,30 @@ export function main() { | ||||
|           c.updateValue("some value"); | ||||
| 
 | ||||
|           expect(a.valid).toBe(true); | ||||
|           expect(a.errors).toBe(null); | ||||
|           expect(a.controlsErrors).toBe(null); | ||||
|         }); | ||||
|       }); | ||||
| 
 | ||||
|       describe("errors", () => { | ||||
|         it("should run the validator when the value changes", () => { | ||||
|           var simpleValidator = (c) => c.controls[0].value != "correct" ? {"broken": true} : null; | ||||
| 
 | ||||
|           var c = new Control(null); | ||||
|           var g = new ControlArray([c], simpleValidator); | ||||
| 
 | ||||
|           c.updateValue("correct"); | ||||
| 
 | ||||
|           expect(g.valid).toEqual(true); | ||||
|           expect(g.errors).toEqual(null); | ||||
| 
 | ||||
|           c.updateValue("incorrect"); | ||||
| 
 | ||||
|           expect(g.valid).toEqual(false); | ||||
|           expect(g.errors).toEqual({"broken": true}); | ||||
|         }); | ||||
|       }); | ||||
| 
 | ||||
| 
 | ||||
|       describe("dirty", () => { | ||||
|         var c: Control; | ||||
|         var a: ControlArray; | ||||
| @ -564,7 +656,6 @@ export function main() { | ||||
|              a.push(c2); | ||||
|            })); | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|       describe("find", () => { | ||||
|         it("should return null when path is null", () => { | ||||
| @ -599,4 +690,5 @@ export function main() { | ||||
|         }); | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
|  | ||||
| @ -90,7 +90,7 @@ export function main() { | ||||
|         var two = new Control("two", validator("b", true)); | ||||
|         var g = new ControlGroup({"one": one, "two": two}); | ||||
| 
 | ||||
|         expect(Validators.group(g)).toEqual({"controls": {"one": {"a": true}, "two": {"b": true}}}); | ||||
|         expect(Validators.group(g)).toEqual({"one": {"a": true}, "two": {"b": true}}); | ||||
|       }); | ||||
| 
 | ||||
|       it("should not include controls that have no errors", () => { | ||||
| @ -98,7 +98,7 @@ export function main() { | ||||
|         var two = new Control("two"); | ||||
|         var g = new ControlGroup({"one": one, "two": two}); | ||||
| 
 | ||||
|         expect(Validators.group(g)).toEqual({"controls": {"one": {"a": true}}}); | ||||
|         expect(Validators.group(g)).toEqual({"one": {"a": true}}); | ||||
|       }); | ||||
| 
 | ||||
|       it("should return null when no errors", () => { | ||||
| @ -106,28 +106,6 @@ export function main() { | ||||
| 
 | ||||
|         expect(Validators.group(g)).toEqual(null); | ||||
|       }); | ||||
| 
 | ||||
|       it("should return control errors mixed with group errors", () => { | ||||
|         var one = new Control("one", validator("a", true)); | ||||
|         var g = new ControlGroup({"one": one}, null, | ||||
|                                  Validators.compose([validator("b", true), Validators.group])); | ||||
| 
 | ||||
|         expect(g.validator(g)).toEqual({"b": true, "controls": {"one": {"a": true}}}); | ||||
|       }); | ||||
| 
 | ||||
|       it("should return nested control group errors mixed with group errors", () => { | ||||
|         var one = new Control("one", validator("a", true)); | ||||
|         var g = new ControlGroup({"one": one}, null, | ||||
|                                  Validators.compose([validator("b", true), Validators.group])); | ||||
|         var two = new Control("two", validator("c", true)); | ||||
|         var gTwo = new ControlGroup({"two": two, "group": g}); | ||||
| 
 | ||||
|         expect(gTwo.validator(gTwo)) | ||||
|             .toEqual({ | ||||
|               "controls": | ||||
|                   {"two": {"c": true}, "group": {"b": true, "controls": {"one": {"a": true}}}} | ||||
|             }); | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|     describe("controlArrayValidator", () => { | ||||
| @ -136,7 +114,7 @@ export function main() { | ||||
|         var two = new Control("two", validator("b", true)); | ||||
|         var a = new ControlArray([one, two]); | ||||
| 
 | ||||
|         expect(Validators.array(a)).toEqual({"controls": [{"a": true}, {"b": true}]}); | ||||
|         expect(Validators.array(a)).toEqual([{"a": true}, {"b": true}]); | ||||
|       }); | ||||
| 
 | ||||
|       it("should not include controls that have no errors", () => { | ||||
| @ -145,7 +123,7 @@ export function main() { | ||||
|         var three = new Control("three"); | ||||
|         var a = new ControlArray([one, two, three]); | ||||
| 
 | ||||
|         expect(Validators.array(a)).toEqual({"controls": [null, {"a": true}, null]}); | ||||
|         expect(Validators.array(a)).toEqual([null, {"a": true}, null]); | ||||
|       }); | ||||
| 
 | ||||
|       it("should return null when no errors", () => { | ||||
| @ -153,22 +131,6 @@ export function main() { | ||||
| 
 | ||||
|         expect(Validators.array(a)).toEqual(null); | ||||
|       }); | ||||
| 
 | ||||
|       it("should return control errors mixed with group errors", () => { | ||||
|         var one = new Control("one", validator("a", true)); | ||||
|         var a = | ||||
|             new ControlArray([one], Validators.compose([validator("b", true), Validators.array])); | ||||
| 
 | ||||
|         expect(a.validator(a)).toEqual({"b": true, "controls": [{"a": true}]}); | ||||
|       }); | ||||
| 
 | ||||
|       it("should return nested array errors ", () => { | ||||
|         var one = new Control("one", validator("a", true)); | ||||
|         var a = new ControlArray([one]); | ||||
|         var a2 = new ControlArray([a]); | ||||
| 
 | ||||
|         expect(Validators.array(a2)).toEqual({"controls": [{"controls": [{"a": true}]}]}); | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
|  | ||||
| @ -43,9 +43,11 @@ var NG_API = [ | ||||
|   'AbstractControl', | ||||
|   'AbstractControl.dirty', | ||||
|   'AbstractControl.errors', | ||||
|   'AbstractControl.controlsErrors', | ||||
|   'AbstractControl.find()', | ||||
|   'AbstractControl.getError()', | ||||
|   'AbstractControl.hasError()', | ||||
|   'AbstractControl.setErrors()', | ||||
|   'AbstractControl.markAsDirty()', | ||||
|   'AbstractControl.markAsPending()', | ||||
|   'AbstractControl.markAsTouched()', | ||||
| @ -55,7 +57,6 @@ var NG_API = [ | ||||
|   'AbstractControl.status', | ||||
|   'AbstractControl.touched', | ||||
|   'AbstractControl.untouched', | ||||
|   'AbstractControl.updateValidity()', | ||||
|   'AbstractControl.updateValueAndValidity()', | ||||
|   'AbstractControl.valid', | ||||
|   'AbstractControl.validator', | ||||
| @ -66,6 +67,7 @@ var NG_API = [ | ||||
|   'AbstractControlDirective.control', | ||||
|   'AbstractControlDirective.dirty', | ||||
|   'AbstractControlDirective.errors', | ||||
|   'AbstractControlDirective.controlsErrors', | ||||
|   'AbstractControlDirective.pristine', | ||||
|   'AbstractControlDirective.touched', | ||||
|   'AbstractControlDirective.untouched', | ||||
| @ -276,6 +278,7 @@ var NG_API = [ | ||||
|   'Control', | ||||
|   'Control.dirty', | ||||
|   'Control.errors', | ||||
|   'Control.controlsErrors', | ||||
|   'Control.find()', | ||||
|   'Control.getError()', | ||||
|   'Control.hasError()', | ||||
| @ -289,7 +292,6 @@ var NG_API = [ | ||||
|   'Control.status', | ||||
|   'Control.touched', | ||||
|   'Control.untouched', | ||||
|   'Control.updateValidity()', | ||||
|   'Control.updateValue()', | ||||
|   'Control.updateValueAndValidity()', | ||||
|   'Control.valid', | ||||
| @ -297,12 +299,14 @@ var NG_API = [ | ||||
|   'Control.validator=', | ||||
|   'Control.value', | ||||
|   'Control.valueChanges', | ||||
|   'Control.setErrors()', | ||||
|   'ControlArray', | ||||
|   'ControlArray.at()', | ||||
|   'ControlArray.controls', | ||||
|   'ControlArray.controls=', | ||||
|   'ControlArray.dirty', | ||||
|   'ControlArray.errors', | ||||
|   'ControlArray.controlsErrors', | ||||
|   'ControlArray.find()', | ||||
|   'ControlArray.getError()', | ||||
|   'ControlArray.hasError()', | ||||
| @ -319,17 +323,18 @@ var NG_API = [ | ||||
|   'ControlArray.status', | ||||
|   'ControlArray.touched', | ||||
|   'ControlArray.untouched', | ||||
|   'ControlArray.updateValidity()', | ||||
|   'ControlArray.updateValueAndValidity()', | ||||
|   'ControlArray.valid', | ||||
|   'ControlArray.validator', | ||||
|   'ControlArray.validator=', | ||||
|   'ControlArray.value', | ||||
|   'ControlArray.valueChanges', | ||||
|   'ControlArray.setErrors()', | ||||
|   'ControlContainer', | ||||
|   'ControlContainer.control', | ||||
|   'ControlContainer.dirty', | ||||
|   'ControlContainer.errors', | ||||
|   'ControlContainer.controlsErrors', | ||||
|   'ControlContainer.formDirective', | ||||
|   'ControlContainer.name', | ||||
|   'ControlContainer.name=', | ||||
| @ -346,6 +351,7 @@ var NG_API = [ | ||||
|   'ControlGroup.controls=', | ||||
|   'ControlGroup.dirty', | ||||
|   'ControlGroup.errors', | ||||
|   'ControlGroup.controlsErrors', | ||||
|   'ControlGroup.exclude()', | ||||
|   'ControlGroup.find()', | ||||
|   'ControlGroup.getError()', | ||||
| @ -361,13 +367,13 @@ var NG_API = [ | ||||
|   'ControlGroup.status', | ||||
|   'ControlGroup.touched', | ||||
|   'ControlGroup.untouched', | ||||
|   'ControlGroup.updateValidity()', | ||||
|   'ControlGroup.updateValueAndValidity()', | ||||
|   'ControlGroup.valid', | ||||
|   'ControlGroup.validator', | ||||
|   'ControlGroup.validator=', | ||||
|   'ControlGroup.value', | ||||
|   'ControlGroup.valueChanges', | ||||
|   'ControlGroup.setErrors()', | ||||
|   'CurrencyPipe', | ||||
|   'CurrencyPipe.transform()', | ||||
|   'CyclicDependencyError', | ||||
| @ -622,6 +628,7 @@ var NG_API = [ | ||||
|   'NgControl.control', | ||||
|   'NgControl.dirty', | ||||
|   'NgControl.errors', | ||||
|   'NgControl.controlsErrors', | ||||
|   'NgControl.name', | ||||
|   'NgControl.name=', | ||||
|   'NgControl.path', | ||||
| @ -638,6 +645,7 @@ var NG_API = [ | ||||
|   'NgControlGroup.control', | ||||
|   'NgControlGroup.dirty', | ||||
|   'NgControlGroup.errors', | ||||
|   'NgControlGroup.controlsErrors', | ||||
|   'NgControlGroup.formDirective', | ||||
|   'NgControlGroup.name', | ||||
|   'NgControlGroup.name=', | ||||
| @ -660,6 +668,7 @@ var NG_API = [ | ||||
|   'NgControlName.control', | ||||
|   'NgControlName.dirty', | ||||
|   'NgControlName.errors', | ||||
|   'NgControlName.controlsErrors', | ||||
|   'NgControlName.formDirective', | ||||
|   'NgControlName.model', | ||||
|   'NgControlName.model=', | ||||
| @ -694,6 +703,7 @@ var NG_API = [ | ||||
|   'NgForm.controls', | ||||
|   'NgForm.dirty', | ||||
|   'NgForm.errors', | ||||
|   'NgForm.controlsErrors', | ||||
|   'NgForm.form', | ||||
|   'NgForm.form=', | ||||
|   'NgForm.formDirective', | ||||
| @ -717,6 +727,7 @@ var NG_API = [ | ||||
|   'NgFormControl.control', | ||||
|   'NgFormControl.dirty', | ||||
|   'NgFormControl.errors', | ||||
|   'NgFormControl.controlsErrors', | ||||
|   'NgFormControl.form', | ||||
|   'NgFormControl.form=', | ||||
|   'NgFormControl.model', | ||||
| @ -748,6 +759,7 @@ var NG_API = [ | ||||
|   'NgFormModel.directives=', | ||||
|   'NgFormModel.dirty', | ||||
|   'NgFormModel.errors', | ||||
|   'NgFormModel.controlsErrors', | ||||
|   'NgFormModel.form', | ||||
|   'NgFormModel.form=', | ||||
|   'NgFormModel.formDirective', | ||||
| @ -774,6 +786,7 @@ var NG_API = [ | ||||
|   'NgModel.control', | ||||
|   'NgModel.dirty', | ||||
|   'NgModel.errors', | ||||
|   'NgModel.controlsErrors', | ||||
|   'NgModel.model', | ||||
|   'NgModel.model=', | ||||
|   'NgModel.name', | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user