11import { StringWrapper , isPresent , isBlank , normalizeBool } from 'angular2/src/core/facade/lang' ;
22import { Observable , EventEmitter , ObservableWrapper } from 'angular2/src/core/facade/async' ;
3+ import { PromiseWrapper } from 'angular2/src/core/facade/promise' ;
34import { StringMapWrapper , ListWrapper } from 'angular2/src/core/facade/collection' ;
45
56/**
@@ -42,16 +43,19 @@ function _find(control: AbstractControl, path: Array<string | number>| string) {
4243 } , control ) ;
4344}
4445
46+ function toObservable ( r : any ) : Observable < any > {
47+ return PromiseWrapper . isPromise ( r ) ? ObservableWrapper . fromPromise ( r ) : r ;
48+ }
49+
4550/**
4651 *
4752 */
4853export abstract class AbstractControl {
4954 /** @internal */
5055 _value : any ;
5156
52- /** @internal */
53- _valueChanges : EventEmitter < any > ;
54-
57+ private _valueChanges : EventEmitter < any > ;
58+ private _statusChanges : EventEmitter < any > ;
5559 private _status : string ;
5660 private _errors : { [ key : string ] : any } ;
5761 private _controlsErrors : any ;
@@ -88,6 +92,8 @@ export abstract class AbstractControl {
8892
8993 get valueChanges ( ) : Observable < any > { return this . _valueChanges ; }
9094
95+ get statusChanges ( ) : Observable < any > { return this . _statusChanges ; }
96+
9197 get pending ( ) : boolean { return this . _status == PENDING ; }
9298
9399 markAsTouched ( ) : void { this . _touched = true ; }
@@ -124,11 +130,12 @@ export abstract class AbstractControl {
124130 this . _status = this . _calculateStatus ( ) ;
125131
126132 if ( this . _status == VALID || this . _status == PENDING ) {
127- this . _runAsyncValidator ( ) ;
133+ this . _runAsyncValidator ( emitEvent ) ;
128134 }
129135
130136 if ( emitEvent ) {
131137 ObservableWrapper . callNext ( this . _valueChanges , this . _value ) ;
138+ ObservableWrapper . callNext ( this . _statusChanges , this . _status ) ;
132139 }
133140
134141 if ( isPresent ( this . _parent ) && ! onlySelf ) {
@@ -138,13 +145,13 @@ export abstract class AbstractControl {
138145
139146 private _runValidator ( ) { return isPresent ( this . validator ) ? this . validator ( this ) : null ; }
140147
141- private _runAsyncValidator ( ) {
148+ private _runAsyncValidator ( emitEvent : boolean ) : void {
142149 if ( isPresent ( this . asyncValidator ) ) {
143150 this . _status = PENDING ;
144151 this . _cancelExistingSubscription ( ) ;
145- var obs = ObservableWrapper . fromPromise ( this . asyncValidator ( this ) ) ;
152+ var obs = toObservable ( this . asyncValidator ( this ) ) ;
146153 this . _asyncValidationSubscription =
147- ObservableWrapper . subscribe ( obs , res => this . setErrors ( res ) ) ;
154+ ObservableWrapper . subscribe ( obs , res => this . setErrors ( res , { emitEvent : emitEvent } ) ) ;
148155 }
149156 }
150157
@@ -177,10 +184,16 @@ export abstract class AbstractControl {
177184 * expect(login.valid).toEqual(true);
178185 * ```
179186 */
180- setErrors ( errors : { [ key : string ] : any } ) : void {
187+ setErrors ( errors : { [ key : string ] : any } , { emitEvent} : { emitEvent ?: boolean } = { } ) : void {
188+ emitEvent = isPresent ( emitEvent ) ? emitEvent : true ;
189+
181190 this . _errors = errors ;
182191 this . _status = this . _calculateStatus ( ) ;
183192
193+ if ( emitEvent ) {
194+ ObservableWrapper . callNext ( this . _statusChanges , this . _status ) ;
195+ }
196+
184197 if ( isPresent ( this . _parent ) ) {
185198 this . _parent . _updateControlsErrors ( ) ;
186199 }
@@ -211,6 +224,13 @@ export abstract class AbstractControl {
211224 }
212225 }
213226
227+ /** @internal */
228+ _initObservables ( ) {
229+ this . _valueChanges = new EventEmitter ( ) ;
230+ this . _statusChanges = new EventEmitter ( ) ;
231+ }
232+
233+
214234 private _calculateStatus ( ) : string {
215235 if ( isPresent ( this . _errors ) ) return INVALID ;
216236 if ( this . _anyControlsHaveStatus ( PENDING ) ) return PENDING ;
@@ -250,7 +270,7 @@ export class Control extends AbstractControl {
250270 super ( validator , asyncValidator ) ;
251271 this . _value = value ;
252272 this . updateValueAndValidity ( { onlySelf : true , emitEvent : false } ) ;
253- this . _valueChanges = new EventEmitter ( ) ;
273+ this . _initObservables ( ) ;
254274 }
255275
256276 /**
@@ -318,8 +338,7 @@ export class ControlGroup extends AbstractControl {
318338 asyncValidator : Function = null ) {
319339 super ( validator , asyncValidator ) ;
320340 this . _optionals = isPresent ( optionals ) ? optionals : { } ;
321- this . _valueChanges = new EventEmitter ( ) ;
322-
341+ this . _initObservables ( ) ;
323342 this . _setParentForControls ( ) ;
324343 this . updateValueAndValidity ( { onlySelf : true , emitEvent : false } ) ;
325344 }
@@ -440,9 +459,7 @@ export class ControlArray extends AbstractControl {
440459 constructor ( public controls : AbstractControl [ ] , validator : Function = null ,
441460 asyncValidator : Function = null ) {
442461 super ( validator , asyncValidator ) ;
443-
444- this . _valueChanges = new EventEmitter ( ) ;
445-
462+ this . _initObservables ( ) ;
446463 this . _setParentForControls ( ) ;
447464 this . updateValueAndValidity ( { onlySelf : true , emitEvent : false } ) ;
448465 }
0 commit comments