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; |     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 pristine(): boolean { return isPresent(this.control) ? this.control.pristine : null; } | ||||||
| 
 | 
 | ||||||
|   get dirty(): boolean { return isPresent(this.control) ? this.control.dirty : 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(); |       var ctrl = new Control(); | ||||||
|       setUpControl(ctrl, dir); |       setUpControl(ctrl, dir); | ||||||
|       container.addControl(dir.name, ctrl); |       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); |       var container = this._findContainer(dir.path); | ||||||
|       if (isPresent(container)) { |       if (isPresent(container)) { | ||||||
|         container.removeControl(dir.name); |         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 container = this._findContainer(dir.path); | ||||||
|       var group = new ControlGroup({}); |       var group = new ControlGroup({}); | ||||||
|       container.addControl(dir.name, group); |       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); |       var container = this._findContainer(dir.path); | ||||||
|       if (isPresent(container)) { |       if (isPresent(container)) { | ||||||
|         container.removeControl(dir.name); |         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 { |   onChanges(changes: {[key: string]: SimpleChange}): void { | ||||||
|     if (this._isControlChanged(changes)) { |     if (this._isControlChanged(changes)) { | ||||||
|       setUpControl(this.form, this); |       setUpControl(this.form, this); | ||||||
|       this.form.updateValidity(); |       this.form.updateValueAndValidity({emitEvent: false}); | ||||||
|     } |     } | ||||||
|     if (isPropertyUpdated(changes, this.viewModel)) { |     if (isPropertyUpdated(changes, this.viewModel)) { | ||||||
|       this.form.updateValue(this.model); |       this.form.updateValue(this.model); | ||||||
|  | |||||||
| @ -112,7 +112,7 @@ export class NgFormModel extends ControlContainer implements Form, | |||||||
|   addControl(dir: NgControl): void { |   addControl(dir: NgControl): void { | ||||||
|     var ctrl: any = this.form.find(dir.path); |     var ctrl: any = this.form.find(dir.path); | ||||||
|     setUpControl(ctrl, dir); |     setUpControl(ctrl, dir); | ||||||
|     ctrl.updateValidity(); |     ctrl.updateValueAndValidity({emitEvent: false}); | ||||||
|     this.directives.push(dir); |     this.directives.push(dir); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -61,7 +61,7 @@ export class NgModel extends NgControl implements OnChanges { | |||||||
|   onChanges(changes: {[key: string]: SimpleChange}) { |   onChanges(changes: {[key: string]: SimpleChange}) { | ||||||
|     if (!this._added) { |     if (!this._added) { | ||||||
|       setUpControl(this._control, this); |       setUpControl(this._control, this); | ||||||
|       this._control.updateValidity(); |       this._control.updateValueAndValidity({emitEvent: false}); | ||||||
|       this._added = true; |       this._added = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -46,22 +46,20 @@ function _find(control: AbstractControl, path: Array<string | number>| string) { | |||||||
| /** | /** | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| export class AbstractControl { | export abstract class AbstractControl { | ||||||
|   /** @internal */ |   /** @internal */ | ||||||
|   _value: any; |   _value: any; | ||||||
|   /** @internal */ | 
 | ||||||
|   _status: string; |  | ||||||
|   /** @internal */ |  | ||||||
|   _errors: {[key: string]: any}; |  | ||||||
|   /** @internal */ |  | ||||||
|   _pristine: boolean = true; |  | ||||||
|   /** @internal */ |  | ||||||
|   _touched: boolean = false; |  | ||||||
|   /** @internal */ |  | ||||||
|   _parent: ControlGroup | ControlArray; |  | ||||||
|   /** @internal */ |   /** @internal */ | ||||||
|   _valueChanges: EventEmitter; |   _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) {} |   constructor(public validator: Function) {} | ||||||
| 
 | 
 | ||||||
|   get value(): any { return this._value; } |   get value(): any { return this._value; } | ||||||
| @ -70,8 +68,16 @@ export class AbstractControl { | |||||||
| 
 | 
 | ||||||
|   get valid(): boolean { return this._status === VALID; } |   get valid(): boolean { return this._status === VALID; } | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    * Returns the errors of this control. | ||||||
|  |    */ | ||||||
|   get errors(): {[key: string]: any} { return this._errors; } |   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 pristine(): boolean { return this._pristine; } | ||||||
| 
 | 
 | ||||||
|   get dirty(): 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; } |   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} = {}): |   updateValueAndValidity({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): | ||||||
|       void { |       void { | ||||||
|     onlySelf = normalizeBool(onlySelf); |     onlySelf = normalizeBool(onlySelf); | ||||||
| @ -124,7 +119,8 @@ export class AbstractControl { | |||||||
|     this._updateValue(); |     this._updateValue(); | ||||||
| 
 | 
 | ||||||
|     this._errors = this.validator(this); |     this._errors = this.validator(this); | ||||||
|     this._status = isPresent(this._errors) ? INVALID : VALID; |     this._controlsErrors = this._calculateControlsErrors(); | ||||||
|  |     this._status = this._calculateStatus(); | ||||||
| 
 | 
 | ||||||
|     if (emitEvent) { |     if (emitEvent) { | ||||||
|       ObservableWrapper.callNext(this._valueChanges, this._value); |       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); } |   find(path: Array<string | number>| string): AbstractControl { return _find(this, path); } | ||||||
| 
 | 
 | ||||||
|   getError(errorCode: string, path: string[] = null): any { |   getError(errorCode: string, path: string[] = null): any { | ||||||
| @ -151,7 +179,23 @@ export class AbstractControl { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** @internal */ |   /** @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) { |   constructor(value: any = null, validator: Function = Validators.nullValidator) { | ||||||
|     super(validator); |     super(validator); | ||||||
|     this._value = value; |     this._value = value; | ||||||
|     this.updateValidity({onlySelf: true}); |     this.updateValueAndValidity({onlySelf: true, emitEvent: false}); | ||||||
|     this._valueChanges = new EventEmitter(); |     this._valueChanges = new EventEmitter(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -203,6 +247,16 @@ export class Control extends AbstractControl { | |||||||
|     this.updateValueAndValidity({onlySelf: onlySelf, emitEvent: emitEvent}); |     this.updateValueAndValidity({onlySelf: onlySelf, emitEvent: emitEvent}); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    * @internal | ||||||
|  |    */ | ||||||
|  |   _updateValue() {} | ||||||
|  | 
 | ||||||
|  |   /** | ||||||
|  |    * @internal | ||||||
|  |    */ | ||||||
|  |   _calculateControlsErrors() { return null; } | ||||||
|  | 
 | ||||||
|   /** |   /** | ||||||
|    * Register a listener for change events. |    * Register a listener for change events. | ||||||
|    */ |    */ | ||||||
| @ -226,14 +280,14 @@ export class ControlGroup extends AbstractControl { | |||||||
|   private _optionals: {[key: string]: boolean}; |   private _optionals: {[key: string]: boolean}; | ||||||
| 
 | 
 | ||||||
|   constructor(public controls: {[key: string]: AbstractControl}, |   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); |     super(validator); | ||||||
|     this._optionals = isPresent(optionals) ? optionals : {}; |     this._optionals = isPresent(optionals) ? optionals : {}; | ||||||
|     this._valueChanges = new EventEmitter(); |     this._valueChanges = new EventEmitter(); | ||||||
| 
 | 
 | ||||||
|     this._setParentForControls(); |     this._setParentForControls(); | ||||||
|     this._value = this._reduceValue(); |     this.updateValueAndValidity({onlySelf: true, emitEvent: false}); | ||||||
|     this.updateValidity({onlySelf: true}); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   addControl(name: string, control: AbstractControl): void { |   addControl(name: string, control: AbstractControl): void { | ||||||
| @ -266,6 +320,9 @@ export class ControlGroup extends AbstractControl { | |||||||
|   /** @internal */ |   /** @internal */ | ||||||
|   _updateValue() { this._value = this._reduceValue(); } |   _updateValue() { this._value = this._reduceValue(); } | ||||||
| 
 | 
 | ||||||
|  |   /** @internal */ | ||||||
|  |   _calculateControlsErrors() { return Validators.group(this); } | ||||||
|  | 
 | ||||||
|   /** @internal */ |   /** @internal */ | ||||||
|   _reduceValue() { |   _reduceValue() { | ||||||
|     return this._reduceChildren({}, (acc, control, name) => { |     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))
 |  * ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
 | ||||||
|  */ |  */ | ||||||
| export class ControlArray extends AbstractControl { | export class ControlArray extends AbstractControl { | ||||||
|   constructor(public controls: AbstractControl[], validator: Function = Validators.array) { |   constructor(public controls: AbstractControl[], validator: Function = Validators.nullValidator) { | ||||||
|     super(validator); |     super(validator); | ||||||
| 
 | 
 | ||||||
|     this._valueChanges = new EventEmitter(); |     this._valueChanges = new EventEmitter(); | ||||||
| 
 | 
 | ||||||
|     this._setParentForControls(); |     this._setParentForControls(); | ||||||
|     this._updateValue(); |     this.updateValueAndValidity({onlySelf: true, emitEvent: false}); | ||||||
|     this.updateValidity({onlySelf: true}); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
| @ -363,6 +419,9 @@ export class ControlArray extends AbstractControl { | |||||||
|   /** @internal */ |   /** @internal */ | ||||||
|   _updateValue(): void { this._value = this.controls.map((control) => control.value); } |   _updateValue(): void { this._value = this.controls.map((control) => control.value); } | ||||||
| 
 | 
 | ||||||
|  |   /** @internal */ | ||||||
|  |   _calculateControlsErrors() { return Validators.array(this); } | ||||||
|  | 
 | ||||||
|   /** @internal */ |   /** @internal */ | ||||||
|   _setParentForControls(): void { |   _setParentForControls(): void { | ||||||
|     this.controls.forEach((control) => { control.setParent(this); }); |     this.controls.forEach((control) => { control.setParent(this); }); | ||||||
|  | |||||||
| @ -62,10 +62,10 @@ export class Validators { | |||||||
|         res[name] = control.errors; |         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 res: any[] = []; | ||||||
|     var anyErrors: boolean = false; |     var anyErrors: boolean = false; | ||||||
|     array.controls.forEach((control) => { |     array.controls.forEach((control) => { | ||||||
| @ -74,6 +74,6 @@ export class Validators { | |||||||
|         anyErrors = true; |         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", () => { |     it("should use default validators when no validators are provided", () => { | ||||||
|       var g = b.group({"login": "some value"}); |       var g = b.group({"login": "some value"}); | ||||||
|       expect(g.controls["login"].validator).toBe(Validators.nullValidator); |       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", () => { |     it("should create control arrays", () => { | ||||||
|  | |||||||
| @ -151,6 +151,61 @@ export function main() { | |||||||
|              c.updateValue("new"); |              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", () => { |     describe("ControlGroup", () => { | ||||||
| @ -176,14 +231,12 @@ export function main() { | |||||||
|         }); |         }); | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
| 
 |       describe("controlsErrors", () => { | ||||||
|       describe("validator", () => { |  | ||||||
|         it("should run the validator with the initial value (valid)", () => { |         it("should run the validator with the initial value (valid)", () => { | ||||||
|           var g = new ControlGroup({"one": new Control('value', Validators.required)}); |           var g = new ControlGroup({"one": new Control('value', Validators.required)}); | ||||||
| 
 | 
 | ||||||
|           expect(g.valid).toEqual(true); |           expect(g.valid).toEqual(true); | ||||||
| 
 |           expect(g.controlsErrors).toEqual(null); | ||||||
|           expect(g.errors).toEqual(null); |  | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         it("should run the validator with the initial value (invalid)", () => { |         it("should run the validator with the initial value (invalid)", () => { | ||||||
| @ -191,8 +244,7 @@ export function main() { | |||||||
|           var g = new ControlGroup({"one": one}); |           var g = new ControlGroup({"one": one}); | ||||||
| 
 | 
 | ||||||
|           expect(g.valid).toEqual(false); |           expect(g.valid).toEqual(false); | ||||||
| 
 |           expect(g.controlsErrors).toEqual({"one": {"required": true}}); | ||||||
|           expect(g.errors).toEqual({"controls": {"one": {"required": true}}}); |  | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         it("should run the validator with the value changes", () => { |         it("should run the validator with the value changes", () => { | ||||||
| @ -201,8 +253,28 @@ export function main() { | |||||||
| 
 | 
 | ||||||
|           c.updateValue("some value"); |           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.valid).toEqual(true); | ||||||
|           expect(g.errors).toEqual(null); |           expect(g.errors).toEqual(null); | ||||||
|  | 
 | ||||||
|  |           c.updateValue("incorrect"); | ||||||
|  | 
 | ||||||
|  |           expect(g.valid).toEqual(false); | ||||||
|  |           expect(g.errors).toEqual({"broken": true}); | ||||||
|         }); |         }); | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
| @ -278,102 +350,102 @@ export function main() { | |||||||
| 
 | 
 | ||||||
|           expect(group.valid).toEqual(false); |           expect(group.valid).toEqual(false); | ||||||
|         }); |         }); | ||||||
|  |       }); | ||||||
| 
 | 
 | ||||||
|         describe("valueChanges", () => { |       describe("valueChanges", () => { | ||||||
|           var g, c1, c2; |         var g, c1, c2; | ||||||
| 
 | 
 | ||||||
|           beforeEach(() => { |         beforeEach(() => { | ||||||
|             c1 = new Control("old1"); |           c1 = new Control("old1"); | ||||||
|             c2 = new Control("old2"); |           c2 = new Control("old2"); | ||||||
|             g = new ControlGroup({"one": c1, "two": c2}, {"two": true}); |           g = new ControlGroup({"one": c1, "two": c2}, {"two": true}); | ||||||
|           }); |  | ||||||
| 
 |  | ||||||
|           it("should fire an event after the value has been updated", |  | ||||||
|              inject([AsyncTestCompleter], (async) => { |  | ||||||
|                ObservableWrapper.subscribe(g.valueChanges, (value) => { |  | ||||||
|                  expect(g.value).toEqual({'one': 'new1', 'two': 'old2'}); |  | ||||||
|                  expect(value).toEqual({'one': 'new1', 'two': 'old2'}); |  | ||||||
|                  async.done(); |  | ||||||
|                }); |  | ||||||
|                c1.updateValue("new1"); |  | ||||||
|              })); |  | ||||||
| 
 |  | ||||||
|           it("should fire an event after the control's observable fired an event", |  | ||||||
|              inject([AsyncTestCompleter], (async) => { |  | ||||||
|                var controlCallbackIsCalled = false; |  | ||||||
| 
 |  | ||||||
|                ObservableWrapper.subscribe(c1.valueChanges, |  | ||||||
|                                            (value) => { controlCallbackIsCalled = true; }); |  | ||||||
| 
 |  | ||||||
|                ObservableWrapper.subscribe(g.valueChanges, (value) => { |  | ||||||
|                  expect(controlCallbackIsCalled).toBe(true); |  | ||||||
|                  async.done(); |  | ||||||
|                }); |  | ||||||
| 
 |  | ||||||
|                c1.updateValue("new1"); |  | ||||||
|              })); |  | ||||||
| 
 |  | ||||||
|           it("should fire an event when a control is excluded", |  | ||||||
|              inject([AsyncTestCompleter], (async) => { |  | ||||||
|                ObservableWrapper.subscribe(g.valueChanges, (value) => { |  | ||||||
|                  expect(value).toEqual({'one': 'old1'}); |  | ||||||
|                  async.done(); |  | ||||||
|                }); |  | ||||||
| 
 |  | ||||||
|                g.exclude("two"); |  | ||||||
|              })); |  | ||||||
| 
 |  | ||||||
|           it("should fire an event when a control is included", |  | ||||||
|              inject([AsyncTestCompleter], (async) => { |  | ||||||
|                g.exclude("two"); |  | ||||||
| 
 |  | ||||||
|                ObservableWrapper.subscribe(g.valueChanges, (value) => { |  | ||||||
|                  expect(value).toEqual({'one': 'old1', 'two': 'old2'}); |  | ||||||
|                  async.done(); |  | ||||||
|                }); |  | ||||||
| 
 |  | ||||||
|                g.include("two"); |  | ||||||
|              })); |  | ||||||
| 
 |  | ||||||
|           it("should fire an event every time a control is updated", |  | ||||||
|              inject([AsyncTestCompleter], (async) => { |  | ||||||
|                var loggedValues = []; |  | ||||||
| 
 |  | ||||||
|                ObservableWrapper.subscribe(g.valueChanges, (value) => { |  | ||||||
|                  loggedValues.push(value); |  | ||||||
| 
 |  | ||||||
|                  if (loggedValues.length == 2) { |  | ||||||
|                    expect(loggedValues) |  | ||||||
|                        .toEqual([{"one": "new1", "two": "old2"}, {"one": "new1", "two": "new2"}]); |  | ||||||
|                    async.done(); |  | ||||||
|                  } |  | ||||||
|                }); |  | ||||||
| 
 |  | ||||||
|                c1.updateValue("new1"); |  | ||||||
|                c2.updateValue("new2"); |  | ||||||
|              })); |  | ||||||
| 
 |  | ||||||
|           xit("should not fire an event when an excluded control is updated", |  | ||||||
|               inject([AsyncTestCompleter], (async) => { |  | ||||||
|                                                // hard to test without hacking zones
 |  | ||||||
|                                            })); |  | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         describe("getError", () => { |         it("should fire an event after the value has been updated", | ||||||
|           it("should return the error when it is present", () => { |            inject([AsyncTestCompleter], (async) => { | ||||||
|             var c = new Control("", Validators.required); |              ObservableWrapper.subscribe(g.valueChanges, (value) => { | ||||||
|             var g = new ControlGroup({"one": c}); |                expect(g.value).toEqual({'one': 'new1', 'two': 'old2'}); | ||||||
|             expect(c.getError("required")).toEqual(true); |                expect(value).toEqual({'one': 'new1', 'two': 'old2'}); | ||||||
|             expect(g.getError("required", ["one"])).toEqual(true); |                async.done(); | ||||||
|           }); |              }); | ||||||
|  |              c1.updateValue("new1"); | ||||||
|  |            })); | ||||||
| 
 | 
 | ||||||
|           it("should return null otherwise", () => { |         it("should fire an event after the control's observable fired an event", | ||||||
|             var c = new Control("not empty", Validators.required); |            inject([AsyncTestCompleter], (async) => { | ||||||
|             var g = new ControlGroup({"one": c}); |              var controlCallbackIsCalled = false; | ||||||
|             expect(c.getError("invalid")).toEqual(null); | 
 | ||||||
|             expect(g.getError("required", ["one"])).toEqual(null); |              ObservableWrapper.subscribe(c1.valueChanges, | ||||||
|             expect(g.getError("required", ["invalid"])).toEqual(null); |                                          (value) => { controlCallbackIsCalled = true; }); | ||||||
|           }); | 
 | ||||||
|  |              ObservableWrapper.subscribe(g.valueChanges, (value) => { | ||||||
|  |                expect(controlCallbackIsCalled).toBe(true); | ||||||
|  |                async.done(); | ||||||
|  |              }); | ||||||
|  | 
 | ||||||
|  |              c1.updateValue("new1"); | ||||||
|  |            })); | ||||||
|  | 
 | ||||||
|  |         it("should fire an event when a control is excluded", | ||||||
|  |            inject([AsyncTestCompleter], (async) => { | ||||||
|  |              ObservableWrapper.subscribe(g.valueChanges, (value) => { | ||||||
|  |                expect(value).toEqual({'one': 'old1'}); | ||||||
|  |                async.done(); | ||||||
|  |              }); | ||||||
|  | 
 | ||||||
|  |              g.exclude("two"); | ||||||
|  |            })); | ||||||
|  | 
 | ||||||
|  |         it("should fire an event when a control is included", | ||||||
|  |            inject([AsyncTestCompleter], (async) => { | ||||||
|  |              g.exclude("two"); | ||||||
|  | 
 | ||||||
|  |              ObservableWrapper.subscribe(g.valueChanges, (value) => { | ||||||
|  |                expect(value).toEqual({'one': 'old1', 'two': 'old2'}); | ||||||
|  |                async.done(); | ||||||
|  |              }); | ||||||
|  | 
 | ||||||
|  |              g.include("two"); | ||||||
|  |            })); | ||||||
|  | 
 | ||||||
|  |         it("should fire an event every time a control is updated", | ||||||
|  |            inject([AsyncTestCompleter], (async) => { | ||||||
|  |              var loggedValues = []; | ||||||
|  | 
 | ||||||
|  |              ObservableWrapper.subscribe(g.valueChanges, (value) => { | ||||||
|  |                loggedValues.push(value); | ||||||
|  | 
 | ||||||
|  |                if (loggedValues.length == 2) { | ||||||
|  |                  expect(loggedValues) | ||||||
|  |                      .toEqual([{"one": "new1", "two": "old2"}, {"one": "new1", "two": "new2"}]); | ||||||
|  |                  async.done(); | ||||||
|  |                } | ||||||
|  |              }); | ||||||
|  | 
 | ||||||
|  |              c1.updateValue("new1"); | ||||||
|  |              c2.updateValue("new2"); | ||||||
|  |            })); | ||||||
|  | 
 | ||||||
|  |         xit("should not fire an event when an excluded control is updated", | ||||||
|  |             inject([AsyncTestCompleter], (async) => { | ||||||
|  |                                              // hard to test without hacking zones
 | ||||||
|  |                                          })); | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       describe("getError", () => { | ||||||
|  |         it("should return the error when it is present", () => { | ||||||
|  |           var c = new Control("", Validators.required); | ||||||
|  |           var g = new ControlGroup({"one": c}); | ||||||
|  |           expect(c.getError("required")).toEqual(true); | ||||||
|  |           expect(g.getError("required", ["one"])).toEqual(true); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         it("should return null otherwise", () => { | ||||||
|  |           var c = new Control("not empty", Validators.required); | ||||||
|  |           var g = new ControlGroup({"one": c}); | ||||||
|  |           expect(c.getError("invalid")).toEqual(null); | ||||||
|  |           expect(g.getError("required", ["one"])).toEqual(null); | ||||||
|  |           expect(g.getError("required", ["invalid"])).toEqual(null); | ||||||
|         }); |         }); | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| @ -428,13 +500,13 @@ export function main() { | |||||||
|         }); |         }); | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|       describe("validator", () => { |       describe("controlsErrors", () => { | ||||||
|         it("should run the validator with the initial value (valid)", () => { |         it("should run the validator with the initial value (valid)", () => { | ||||||
|           var a = new ControlArray( |           var a = new ControlArray( | ||||||
|               [new Control(1, Validators.required), new Control(2, Validators.required)]); |               [new Control(1, Validators.required), new Control(2, Validators.required)]); | ||||||
| 
 | 
 | ||||||
|           expect(a.valid).toBe(true); |           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)", () => { |         it("should run the validator with the initial value (invalid)", () => { | ||||||
| @ -445,7 +517,7 @@ export function main() { | |||||||
|           ]); |           ]); | ||||||
| 
 | 
 | ||||||
|           expect(a.valid).toBe(false); |           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", () => { |         it("should run the validator when the value changes", () => { | ||||||
| @ -457,10 +529,30 @@ export function main() { | |||||||
|           c.updateValue("some value"); |           c.updateValue("some value"); | ||||||
| 
 | 
 | ||||||
|           expect(a.valid).toBe(true); |           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", () => { |       describe("dirty", () => { | ||||||
|         var c: Control; |         var c: Control; | ||||||
|         var a: ControlArray; |         var a: ControlArray; | ||||||
| @ -564,38 +656,38 @@ export function main() { | |||||||
|              a.push(c2); |              a.push(c2); | ||||||
|            })); |            })); | ||||||
|       }); |       }); | ||||||
|     }); |  | ||||||
| 
 | 
 | ||||||
|     describe("find", () => { |       describe("find", () => { | ||||||
|       it("should return null when path is null", () => { |         it("should return null when path is null", () => { | ||||||
|         var g = new ControlGroup({}); |           var g = new ControlGroup({}); | ||||||
|         expect(g.find(null)).toEqual(null); |           expect(g.find(null)).toEqual(null); | ||||||
|       }); |         }); | ||||||
| 
 | 
 | ||||||
|       it("should return null when path is empty", () => { |         it("should return null when path is empty", () => { | ||||||
|         var g = new ControlGroup({}); |           var g = new ControlGroup({}); | ||||||
|         expect(g.find([])).toEqual(null); |           expect(g.find([])).toEqual(null); | ||||||
|       }); |         }); | ||||||
| 
 | 
 | ||||||
|       it("should return null when path is invalid", () => { |         it("should return null when path is invalid", () => { | ||||||
|         var g = new ControlGroup({}); |           var g = new ControlGroup({}); | ||||||
|         expect(g.find(["one", "two"])).toEqual(null); |           expect(g.find(["one", "two"])).toEqual(null); | ||||||
|       }); |         }); | ||||||
| 
 | 
 | ||||||
|       it("should return a child of a control group", () => { |         it("should return a child of a control group", () => { | ||||||
|         var g = new ControlGroup( |           var g = new ControlGroup( | ||||||
|             {"one": new Control("111"), "nested": new ControlGroup({"two": new Control("222")})}); |               {"one": new Control("111"), "nested": new ControlGroup({"two": new Control("222")})}); | ||||||
| 
 | 
 | ||||||
|         expect(g.find(["nested", "two"]).value).toEqual("222"); |           expect(g.find(["nested", "two"]).value).toEqual("222"); | ||||||
|         expect(g.find(["one"]).value).toEqual("111"); |           expect(g.find(["one"]).value).toEqual("111"); | ||||||
|         expect(g.find("nested/two").value).toEqual("222"); |           expect(g.find("nested/two").value).toEqual("222"); | ||||||
|         expect(g.find("one").value).toEqual("111"); |           expect(g.find("one").value).toEqual("111"); | ||||||
|       }); |         }); | ||||||
| 
 | 
 | ||||||
|       it("should return an element of an array", () => { |         it("should return an element of an array", () => { | ||||||
|         var g = new ControlGroup({"array": new ControlArray([new Control("111")])}); |           var g = new ControlGroup({"array": new ControlArray([new Control("111")])}); | ||||||
| 
 | 
 | ||||||
|         expect(g.find(["array", 0]).value).toEqual("111"); |           expect(g.find(["array", 0]).value).toEqual("111"); | ||||||
|  |         }); | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
|  | |||||||
| @ -90,7 +90,7 @@ export function main() { | |||||||
|         var two = new Control("two", validator("b", true)); |         var two = new Control("two", validator("b", true)); | ||||||
|         var g = new ControlGroup({"one": one, "two": two}); |         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", () => { |       it("should not include controls that have no errors", () => { | ||||||
| @ -98,7 +98,7 @@ export function main() { | |||||||
|         var two = new Control("two"); |         var two = new Control("two"); | ||||||
|         var g = new ControlGroup({"one": one, "two": 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", () => { |       it("should return null when no errors", () => { | ||||||
| @ -106,28 +106,6 @@ export function main() { | |||||||
| 
 | 
 | ||||||
|         expect(Validators.group(g)).toEqual(null); |         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", () => { |     describe("controlArrayValidator", () => { | ||||||
| @ -136,7 +114,7 @@ export function main() { | |||||||
|         var two = new Control("two", validator("b", true)); |         var two = new Control("two", validator("b", true)); | ||||||
|         var a = new ControlArray([one, two]); |         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", () => { |       it("should not include controls that have no errors", () => { | ||||||
| @ -145,7 +123,7 @@ export function main() { | |||||||
|         var three = new Control("three"); |         var three = new Control("three"); | ||||||
|         var a = new ControlArray([one, two, 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", () => { |       it("should return null when no errors", () => { | ||||||
| @ -153,22 +131,6 @@ export function main() { | |||||||
| 
 | 
 | ||||||
|         expect(Validators.array(a)).toEqual(null); |         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', | ||||||
|   'AbstractControl.dirty', |   'AbstractControl.dirty', | ||||||
|   'AbstractControl.errors', |   'AbstractControl.errors', | ||||||
|  |   'AbstractControl.controlsErrors', | ||||||
|   'AbstractControl.find()', |   'AbstractControl.find()', | ||||||
|   'AbstractControl.getError()', |   'AbstractControl.getError()', | ||||||
|   'AbstractControl.hasError()', |   'AbstractControl.hasError()', | ||||||
|  |   'AbstractControl.setErrors()', | ||||||
|   'AbstractControl.markAsDirty()', |   'AbstractControl.markAsDirty()', | ||||||
|   'AbstractControl.markAsPending()', |   'AbstractControl.markAsPending()', | ||||||
|   'AbstractControl.markAsTouched()', |   'AbstractControl.markAsTouched()', | ||||||
| @ -55,7 +57,6 @@ var NG_API = [ | |||||||
|   'AbstractControl.status', |   'AbstractControl.status', | ||||||
|   'AbstractControl.touched', |   'AbstractControl.touched', | ||||||
|   'AbstractControl.untouched', |   'AbstractControl.untouched', | ||||||
|   'AbstractControl.updateValidity()', |  | ||||||
|   'AbstractControl.updateValueAndValidity()', |   'AbstractControl.updateValueAndValidity()', | ||||||
|   'AbstractControl.valid', |   'AbstractControl.valid', | ||||||
|   'AbstractControl.validator', |   'AbstractControl.validator', | ||||||
| @ -66,6 +67,7 @@ var NG_API = [ | |||||||
|   'AbstractControlDirective.control', |   'AbstractControlDirective.control', | ||||||
|   'AbstractControlDirective.dirty', |   'AbstractControlDirective.dirty', | ||||||
|   'AbstractControlDirective.errors', |   'AbstractControlDirective.errors', | ||||||
|  |   'AbstractControlDirective.controlsErrors', | ||||||
|   'AbstractControlDirective.pristine', |   'AbstractControlDirective.pristine', | ||||||
|   'AbstractControlDirective.touched', |   'AbstractControlDirective.touched', | ||||||
|   'AbstractControlDirective.untouched', |   'AbstractControlDirective.untouched', | ||||||
| @ -276,6 +278,7 @@ var NG_API = [ | |||||||
|   'Control', |   'Control', | ||||||
|   'Control.dirty', |   'Control.dirty', | ||||||
|   'Control.errors', |   'Control.errors', | ||||||
|  |   'Control.controlsErrors', | ||||||
|   'Control.find()', |   'Control.find()', | ||||||
|   'Control.getError()', |   'Control.getError()', | ||||||
|   'Control.hasError()', |   'Control.hasError()', | ||||||
| @ -289,7 +292,6 @@ var NG_API = [ | |||||||
|   'Control.status', |   'Control.status', | ||||||
|   'Control.touched', |   'Control.touched', | ||||||
|   'Control.untouched', |   'Control.untouched', | ||||||
|   'Control.updateValidity()', |  | ||||||
|   'Control.updateValue()', |   'Control.updateValue()', | ||||||
|   'Control.updateValueAndValidity()', |   'Control.updateValueAndValidity()', | ||||||
|   'Control.valid', |   'Control.valid', | ||||||
| @ -297,12 +299,14 @@ var NG_API = [ | |||||||
|   'Control.validator=', |   'Control.validator=', | ||||||
|   'Control.value', |   'Control.value', | ||||||
|   'Control.valueChanges', |   'Control.valueChanges', | ||||||
|  |   'Control.setErrors()', | ||||||
|   'ControlArray', |   'ControlArray', | ||||||
|   'ControlArray.at()', |   'ControlArray.at()', | ||||||
|   'ControlArray.controls', |   'ControlArray.controls', | ||||||
|   'ControlArray.controls=', |   'ControlArray.controls=', | ||||||
|   'ControlArray.dirty', |   'ControlArray.dirty', | ||||||
|   'ControlArray.errors', |   'ControlArray.errors', | ||||||
|  |   'ControlArray.controlsErrors', | ||||||
|   'ControlArray.find()', |   'ControlArray.find()', | ||||||
|   'ControlArray.getError()', |   'ControlArray.getError()', | ||||||
|   'ControlArray.hasError()', |   'ControlArray.hasError()', | ||||||
| @ -319,17 +323,18 @@ var NG_API = [ | |||||||
|   'ControlArray.status', |   'ControlArray.status', | ||||||
|   'ControlArray.touched', |   'ControlArray.touched', | ||||||
|   'ControlArray.untouched', |   'ControlArray.untouched', | ||||||
|   'ControlArray.updateValidity()', |  | ||||||
|   'ControlArray.updateValueAndValidity()', |   'ControlArray.updateValueAndValidity()', | ||||||
|   'ControlArray.valid', |   'ControlArray.valid', | ||||||
|   'ControlArray.validator', |   'ControlArray.validator', | ||||||
|   'ControlArray.validator=', |   'ControlArray.validator=', | ||||||
|   'ControlArray.value', |   'ControlArray.value', | ||||||
|   'ControlArray.valueChanges', |   'ControlArray.valueChanges', | ||||||
|  |   'ControlArray.setErrors()', | ||||||
|   'ControlContainer', |   'ControlContainer', | ||||||
|   'ControlContainer.control', |   'ControlContainer.control', | ||||||
|   'ControlContainer.dirty', |   'ControlContainer.dirty', | ||||||
|   'ControlContainer.errors', |   'ControlContainer.errors', | ||||||
|  |   'ControlContainer.controlsErrors', | ||||||
|   'ControlContainer.formDirective', |   'ControlContainer.formDirective', | ||||||
|   'ControlContainer.name', |   'ControlContainer.name', | ||||||
|   'ControlContainer.name=', |   'ControlContainer.name=', | ||||||
| @ -346,6 +351,7 @@ var NG_API = [ | |||||||
|   'ControlGroup.controls=', |   'ControlGroup.controls=', | ||||||
|   'ControlGroup.dirty', |   'ControlGroup.dirty', | ||||||
|   'ControlGroup.errors', |   'ControlGroup.errors', | ||||||
|  |   'ControlGroup.controlsErrors', | ||||||
|   'ControlGroup.exclude()', |   'ControlGroup.exclude()', | ||||||
|   'ControlGroup.find()', |   'ControlGroup.find()', | ||||||
|   'ControlGroup.getError()', |   'ControlGroup.getError()', | ||||||
| @ -361,13 +367,13 @@ var NG_API = [ | |||||||
|   'ControlGroup.status', |   'ControlGroup.status', | ||||||
|   'ControlGroup.touched', |   'ControlGroup.touched', | ||||||
|   'ControlGroup.untouched', |   'ControlGroup.untouched', | ||||||
|   'ControlGroup.updateValidity()', |  | ||||||
|   'ControlGroup.updateValueAndValidity()', |   'ControlGroup.updateValueAndValidity()', | ||||||
|   'ControlGroup.valid', |   'ControlGroup.valid', | ||||||
|   'ControlGroup.validator', |   'ControlGroup.validator', | ||||||
|   'ControlGroup.validator=', |   'ControlGroup.validator=', | ||||||
|   'ControlGroup.value', |   'ControlGroup.value', | ||||||
|   'ControlGroup.valueChanges', |   'ControlGroup.valueChanges', | ||||||
|  |   'ControlGroup.setErrors()', | ||||||
|   'CurrencyPipe', |   'CurrencyPipe', | ||||||
|   'CurrencyPipe.transform()', |   'CurrencyPipe.transform()', | ||||||
|   'CyclicDependencyError', |   'CyclicDependencyError', | ||||||
| @ -622,6 +628,7 @@ var NG_API = [ | |||||||
|   'NgControl.control', |   'NgControl.control', | ||||||
|   'NgControl.dirty', |   'NgControl.dirty', | ||||||
|   'NgControl.errors', |   'NgControl.errors', | ||||||
|  |   'NgControl.controlsErrors', | ||||||
|   'NgControl.name', |   'NgControl.name', | ||||||
|   'NgControl.name=', |   'NgControl.name=', | ||||||
|   'NgControl.path', |   'NgControl.path', | ||||||
| @ -638,6 +645,7 @@ var NG_API = [ | |||||||
|   'NgControlGroup.control', |   'NgControlGroup.control', | ||||||
|   'NgControlGroup.dirty', |   'NgControlGroup.dirty', | ||||||
|   'NgControlGroup.errors', |   'NgControlGroup.errors', | ||||||
|  |   'NgControlGroup.controlsErrors', | ||||||
|   'NgControlGroup.formDirective', |   'NgControlGroup.formDirective', | ||||||
|   'NgControlGroup.name', |   'NgControlGroup.name', | ||||||
|   'NgControlGroup.name=', |   'NgControlGroup.name=', | ||||||
| @ -660,6 +668,7 @@ var NG_API = [ | |||||||
|   'NgControlName.control', |   'NgControlName.control', | ||||||
|   'NgControlName.dirty', |   'NgControlName.dirty', | ||||||
|   'NgControlName.errors', |   'NgControlName.errors', | ||||||
|  |   'NgControlName.controlsErrors', | ||||||
|   'NgControlName.formDirective', |   'NgControlName.formDirective', | ||||||
|   'NgControlName.model', |   'NgControlName.model', | ||||||
|   'NgControlName.model=', |   'NgControlName.model=', | ||||||
| @ -694,6 +703,7 @@ var NG_API = [ | |||||||
|   'NgForm.controls', |   'NgForm.controls', | ||||||
|   'NgForm.dirty', |   'NgForm.dirty', | ||||||
|   'NgForm.errors', |   'NgForm.errors', | ||||||
|  |   'NgForm.controlsErrors', | ||||||
|   'NgForm.form', |   'NgForm.form', | ||||||
|   'NgForm.form=', |   'NgForm.form=', | ||||||
|   'NgForm.formDirective', |   'NgForm.formDirective', | ||||||
| @ -717,6 +727,7 @@ var NG_API = [ | |||||||
|   'NgFormControl.control', |   'NgFormControl.control', | ||||||
|   'NgFormControl.dirty', |   'NgFormControl.dirty', | ||||||
|   'NgFormControl.errors', |   'NgFormControl.errors', | ||||||
|  |   'NgFormControl.controlsErrors', | ||||||
|   'NgFormControl.form', |   'NgFormControl.form', | ||||||
|   'NgFormControl.form=', |   'NgFormControl.form=', | ||||||
|   'NgFormControl.model', |   'NgFormControl.model', | ||||||
| @ -748,6 +759,7 @@ var NG_API = [ | |||||||
|   'NgFormModel.directives=', |   'NgFormModel.directives=', | ||||||
|   'NgFormModel.dirty', |   'NgFormModel.dirty', | ||||||
|   'NgFormModel.errors', |   'NgFormModel.errors', | ||||||
|  |   'NgFormModel.controlsErrors', | ||||||
|   'NgFormModel.form', |   'NgFormModel.form', | ||||||
|   'NgFormModel.form=', |   'NgFormModel.form=', | ||||||
|   'NgFormModel.formDirective', |   'NgFormModel.formDirective', | ||||||
| @ -774,6 +786,7 @@ var NG_API = [ | |||||||
|   'NgModel.control', |   'NgModel.control', | ||||||
|   'NgModel.dirty', |   'NgModel.dirty', | ||||||
|   'NgModel.errors', |   'NgModel.errors', | ||||||
|  |   'NgModel.controlsErrors', | ||||||
|   'NgModel.model', |   'NgModel.model', | ||||||
|   'NgModel.model=', |   'NgModel.model=', | ||||||
|   'NgModel.name', |   'NgModel.name', | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user