@@ -46,22 +46,20 @@ function _find(control: AbstractControl, path: Array<string | number>| string) {
4646/** 
4747 * 
4848 */ 
49- export  class  AbstractControl  { 
49+ export  abstract   class  AbstractControl  { 
5050 /** @internal  */ 
5151 _value : any ; 
52-  /** @internal  */ 
53-  _status : string ; 
54-  /** @internal  */ 
55-  _errors : { [ key : string ] : any } ; 
56-  /** @internal  */ 
57-  _pristine : boolean  =  true ; 
58-  /** @internal  */ 
59-  _touched : boolean  =  false ; 
60-  /** @internal  */ 
61-  _parent : ControlGroup  |  ControlArray ; 
52+ 
6253 /** @internal  */ 
6354 _valueChanges : EventEmitter ; 
6455
56+  private  _status : string ; 
57+  private  _errors : { [ key : string ] : any } ; 
58+  private  _controlsErrors : any ; 
59+  private  _pristine : boolean  =  true ; 
60+  private  _touched : boolean  =  false ; 
61+  private  _parent : ControlGroup  |  ControlArray ; 
62+ 
6563 constructor ( public  validator : Function )  { } 
6664
6765 get  value ( ) : any  {  return  this . _value ;  } 
@@ -70,8 +68,16 @@ export class AbstractControl {
7068
7169 get  valid ( ) : boolean  {  return  this . _status  ===  VALID ;  } 
7270
71+  /** 
72+  * Returns the errors of this control. 
73+  */ 
7374 get  errors ( ) : { [ key : string ] : any }  {  return  this . _errors ;  } 
7475
76+  /** 
77+  * Returns the errors of the child controls. 
78+  */ 
79+  get  controlsErrors ( ) : any  {  return  this . _controlsErrors ;  } 
80+ 
7581 get  pristine ( ) : boolean  {  return  this . _pristine ;  } 
7682
7783 get  dirty ( ) : boolean  {  return  ! this . pristine ;  } 
@@ -105,17 +111,6 @@ export class AbstractControl {
105111
106112 setParent ( parent : ControlGroup  |  ControlArray ) : void {  this . _parent  =  parent ;  } 
107113
108-  updateValidity ( { onlySelf} : { onlySelf ?: boolean }  =  { } ) : void { 
109-  onlySelf  =  normalizeBool ( onlySelf ) ; 
110- 
111-  this . _errors  =  this . validator ( this ) ; 
112-  this . _status  =  isPresent ( this . _errors )  ? INVALID  : VALID ; 
113- 
114-  if  ( isPresent ( this . _parent )  &&  ! onlySelf )  { 
115-  this . _parent . updateValidity ( { onlySelf : onlySelf } ) ; 
116-  } 
117-  } 
118- 
119114 updateValueAndValidity ( { onlySelf,  emitEvent} : { onlySelf ?: boolean ,  emitEvent ?: boolean }  =  { } ) :
120115 void { 
121116 onlySelf  =  normalizeBool ( onlySelf ) ; 
@@ -124,7 +119,8 @@ export class AbstractControl {
124119 this . _updateValue ( ) ; 
125120
126121 this . _errors  =  this . validator ( this ) ; 
127-  this . _status  =  isPresent ( this . _errors )  ? INVALID  : VALID ; 
122+  this . _controlsErrors  =  this . _calculateControlsErrors ( ) ; 
123+  this . _status  =  this . _calculateStatus ( ) ; 
128124
129125 if  ( emitEvent )  { 
130126 ObservableWrapper . callNext ( this . _valueChanges ,  this . _value ) ; 
@@ -135,6 +131,38 @@ export class AbstractControl {
135131 } 
136132 } 
137133
134+  /** 
135+  * Sets errors on a control. 
136+  * 
137+  * This is used when validations are run not automatically, but manually by the user. 
138+  * 
139+  * Calling `setErrors` will also update the validity of the parent control. 
140+  * 
141+  * ## Usage 
142+  * 
143+  * ``` 
144+  * var login = new Control("someLogin"); 
145+  * login.setErrors({ 
146+  * "notUnique": true 
147+  * }); 
148+  * 
149+  * expect(login.valid).toEqual(false); 
150+  * expect(login.errors).toEqual({"notUnique": true}); 
151+  * 
152+  * login.updateValue("someOtherLogin"); 
153+  * 
154+  * expect(login.valid).toEqual(true); 
155+  * ``` 
156+  */ 
157+  setErrors ( errors : { [ key : string ] : any } ) : void { 
158+  this . _errors  =  errors ; 
159+  this . _status  =  this . _calculateStatus ( ) ; 
160+ 
161+  if  ( isPresent ( this . _parent ) )  { 
162+  this . _parent . _updateControlsErrors ( ) ; 
163+  } 
164+  } 
165+ 
138166 find ( path : Array < string  |  number > |  string ) : AbstractControl  {  return  _find ( this ,  path ) ;  } 
139167
140168 getError ( errorCode : string ,  path : string [ ]  =  null ) : any  { 
@@ -151,7 +179,23 @@ export class AbstractControl {
151179 } 
152180
153181 /** @internal  */ 
154-  _updateValue ( ) : void { } 
182+  _updateControlsErrors ( ) : void { 
183+  this . _controlsErrors  =  this . _calculateControlsErrors ( ) ; 
184+  this . _status  =  this . _calculateStatus ( ) ; 
185+ 
186+  if  ( isPresent ( this . _parent ) )  { 
187+  this . _parent . _updateControlsErrors ( ) ; 
188+  } 
189+  } 
190+ 
191+  private  _calculateStatus ( ) : string  { 
192+  return  isPresent ( this . _errors )  ||  isPresent ( this . _controlsErrors )  ? INVALID  : VALID ; 
193+  } 
194+ 
195+  /** @internal  */ 
196+  abstract  _updateValue ( ) : void ; 
197+  /** @internal  */ 
198+  abstract  _calculateControlsErrors ( ) : any ; 
155199} 
156200
157201/** 
@@ -177,7 +221,7 @@ export class Control extends AbstractControl {
177221 constructor ( value : any  =  null ,  validator : Function  =  Validators . nullValidator )  { 
178222 super ( validator ) ; 
179223 this . _value  =  value ; 
180-  this . updateValidity ( { onlySelf : true } ) ; 
224+  this . updateValueAndValidity ( { onlySelf : true ,   emitEvent :  false } ) ; 
181225 this . _valueChanges  =  new  EventEmitter ( ) ; 
182226 } 
183227
@@ -203,6 +247,16 @@ export class Control extends AbstractControl {
203247 this . updateValueAndValidity ( { onlySelf : onlySelf ,  emitEvent : emitEvent } ) ; 
204248 } 
205249
250+  /** 
251+  * @internal  
252+  */ 
253+  _updateValue ( )  { } 
254+ 
255+  /** 
256+  * @internal  
257+  */ 
258+  _calculateControlsErrors ( )  {  return  null ;  } 
259+ 
206260 /** 
207261 * Register a listener for change events. 
208262 */ 
@@ -226,14 +280,14 @@ export class ControlGroup extends AbstractControl {
226280 private  _optionals : { [ key : string ] : boolean } ; 
227281
228282 constructor ( public  controls : { [ key : string ] : AbstractControl } , 
229-  optionals : { [ key : string ] : boolean }  =  null ,  validator : Function  =  Validators . group )  { 
283+  optionals : { [ key : string ] : boolean }  =  null , 
284+  validator : Function  =  Validators . nullValidator )  { 
230285 super ( validator ) ; 
231286 this . _optionals  =  isPresent ( optionals )  ? optionals  : { } ; 
232287 this . _valueChanges  =  new  EventEmitter ( ) ; 
233288
234289 this . _setParentForControls ( ) ; 
235-  this . _value  =  this . _reduceValue ( ) ; 
236-  this . updateValidity ( { onlySelf : true } ) ; 
290+  this . updateValueAndValidity ( { onlySelf : true ,  emitEvent : false } ) ; 
237291 } 
238292
239293 addControl ( name : string ,  control : AbstractControl ) : void { 
@@ -266,6 +320,9 @@ export class ControlGroup extends AbstractControl {
266320 /** @internal  */ 
267321 _updateValue ( )  {  this . _value  =  this . _reduceValue ( ) ;  } 
268322
323+  /** @internal  */ 
324+  _calculateControlsErrors ( )  {  return  Validators . group ( this ) ;  } 
325+ 
269326 /** @internal  */ 
270327 _reduceValue ( )  { 
271328 return  this . _reduceChildren ( { } ,  ( acc ,  control ,  name )  =>  { 
@@ -314,14 +371,13 @@ export class ControlGroup extends AbstractControl {
314371 * ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview)) 
315372 */ 
316373export  class  ControlArray  extends  AbstractControl  { 
317-  constructor ( public  controls : AbstractControl [ ] ,  validator : Function  =  Validators . array )  { 
374+  constructor ( public  controls : AbstractControl [ ] ,  validator : Function  =  Validators . nullValidator )  { 
318375 super ( validator ) ; 
319376
320377 this . _valueChanges  =  new  EventEmitter ( ) ; 
321378
322379 this . _setParentForControls ( ) ; 
323-  this . _updateValue ( ) ; 
324-  this . updateValidity ( { onlySelf : true } ) ; 
380+  this . updateValueAndValidity ( { onlySelf : true ,  emitEvent : false } ) ; 
325381 } 
326382
327383 /** 
@@ -363,6 +419,9 @@ export class ControlArray extends AbstractControl {
363419 /** @internal  */ 
364420 _updateValue ( ) : void {  this . _value  =  this . controls . map ( ( control )  =>  control . value ) ;  } 
365421
422+  /** @internal  */ 
423+  _calculateControlsErrors ( )  {  return  Validators . array ( this ) ;  } 
424+ 
366425 /** @internal  */ 
367426 _setParentForControls ( ) : void { 
368427 this . controls . forEach ( ( control )  =>  {  control . setParent ( this ) ;  } ) ; 
0 commit comments