1- import { StringWrapper , isPresent } from 'angular2/src/facade/lang' ;
1+ import { StringWrapper , isPresent , isBlank } from 'angular2/src/facade/lang' ;
22import { Observable , EventEmitter , ObservableWrapper } from 'angular2/src/facade/async' ;
33import { StringMap , StringMapWrapper , ListWrapper , List } from 'angular2/src/facade/collection' ;
44import { Validators } from './validators' ;
@@ -21,6 +21,24 @@ export function isControl(c: Object): boolean {
2121 return c instanceof AbstractControl ;
2222}
2323
24+ function _find ( c : AbstractControl , path : List < string | number > | string ) {
25+ if ( isBlank ( path ) ) return null ;
26+ if ( ! ( path instanceof List ) ) {
27+ path = StringWrapper . split ( < string > path , new RegExp ( "/" ) ) ;
28+ }
29+ if ( ListWrapper . isEmpty ( path ) ) return null ;
30+
31+ return ListWrapper . reduce ( < List < string | number > > path , ( v , name ) => {
32+ if ( v instanceof ControlGroup ) {
33+ return isPresent ( v . controls [ name ] ) ? v . controls [ name ] : null ;
34+ } else if ( v instanceof ControlArray ) {
35+ var index = < number > name ;
36+ return isPresent ( v . at ( index ) ) ? v . at ( index ) : null ;
37+ } else {
38+ return null ;
39+ }
40+ } , c ) ;
41+ }
2442
2543/**
2644 * Omitting from external API doc as this is really an abstract internal concept.
@@ -31,7 +49,7 @@ export class AbstractControl {
3149 _errors : StringMap < string , any > ;
3250 _pristine : boolean ;
3351 _touched : boolean ;
34- _parent : any ; /* ControlGroup | ControlArray */
52+ _parent : ControlGroup | ControlArray ;
3553 validator : Function ;
3654
3755 _valueChanges : EventEmitter ;
@@ -78,6 +96,7 @@ export class AbstractControl {
7896
7997 this . _errors = this . validator ( this ) ;
8098 this . _status = isPresent ( this . _errors ) ? INVALID : VALID ;
99+
81100 if ( isPresent ( this . _parent ) && ! onlySelf ) {
82101 this . _parent . updateValidity ( { onlySelf : onlySelf } ) ;
83102 }
@@ -101,6 +120,21 @@ export class AbstractControl {
101120 }
102121 }
103122
123+ find ( path : List < string | number > | string ) : AbstractControl { return _find ( this , path ) ; }
124+
125+ getError ( errorCode : string , path : List < string > = null ) {
126+ var c = this . find ( path ) ;
127+ if ( isPresent ( c ) && isPresent ( c . _errors ) ) {
128+ return StringMapWrapper . get ( c . _errors , errorCode ) ;
129+ } else {
130+ return null ;
131+ }
132+ }
133+
134+ hasError ( errorCode : string , path : List < string > = null ) {
135+ return isPresent ( this . getError ( errorCode , path ) ) ;
136+ }
137+
104138 _updateValue ( ) : void { }
105139}
106140
@@ -168,7 +202,10 @@ export class ControlGroup extends AbstractControl {
168202 this . updateValidity ( { onlySelf : true } ) ;
169203 }
170204
171- addControl ( name : string , c : AbstractControl ) { this . controls [ name ] = c ; }
205+ addControl ( name : string , c : AbstractControl ) {
206+ this . controls [ name ] = c ;
207+ c . setParent ( this ) ;
208+ }
172209
173210 removeControl ( name : string ) { StringMapWrapper . delete ( this . controls , name ) ; }
174211
@@ -187,18 +224,6 @@ export class ControlGroup extends AbstractControl {
187224 return c && this . _included ( controlName ) ;
188225 }
189226
190- find ( path : string | List < string > ) : AbstractControl {
191- if ( ! ( path instanceof List ) ) {
192- path = StringWrapper . split ( < string > path , new RegExp ( "/" ) ) ;
193- }
194-
195- return ListWrapper . reduce (
196- < List < string > > path , ( v , name ) => v instanceof ControlGroup && isPresent ( v . controls [ name ] ) ?
197- v . controls [ name ] :
198- null ,
199- this ) ;
200- }
201-
202227 _setParentForControls ( ) {
203228 StringMapWrapper . forEach ( this . controls , ( control , name ) => { control . setParent ( this ) ; } ) ;
204229 }
0 commit comments