11import { Inject , Injectable , Optional } from '@angular/core' ;
2- import { AbstractControl } from '@angular/forms' ;
3- import { coerceArray , filterControlKeys , filterNil , isBrowser , isObject , mergeDeep } from './utils' ;
4- import { merge , Observable , Subject , Subscription } from 'rxjs' ;
5- import { debounceTime , distinctUntilChanged , filter , map } from 'rxjs/operators' ;
2+ import { AbstractControl , FormGroup } from '@angular/forms' ;
3+ import { coerceArray , filterControlKeys , filterNil , isBrowser , mergeDeep } from './utils' ;
4+ import { EMPTY , merge , Observable , Subject , Subscription , timer } from 'rxjs' ;
5+ import { debounce , distinctUntilChanged , filter , map , mapTo , tap } from 'rxjs/operators' ;
66import { FormsStore } from './forms-manager.store' ;
77import { Control , ControlFactory , FormKeys , HashMap , UpsertConfig } from './types' ;
88import { Config , NG_FORMS_MANAGER_CONFIG , NgFormsManagerConfig } from './config' ;
99import { isEqual } from './isEqual' ;
1010import { deleteControl , findControl , handleFormArray , toStore } from './builders' ;
1111
12+ const NO_DEBOUNCE = Symbol ( 'NO_DEBOUNCE' ) ;
13+
1214@Injectable ( { providedIn : 'root' } )
1315export class NgFormsManager < FormsState = any > {
1416 private readonly store : FormsStore < FormsState > ;
@@ -374,10 +376,10 @@ export class NgFormsManager<FormsState = any> {
374376 }
375377
376378 const unsubscribe = merge (
377- control . valueChanges ,
378- control . statusChanges . pipe ( distinctUntilChanged ( ) )
379+ control . statusChanges . pipe ( distinctUntilChanged ( ) ) ,
380+ ... this . getValueChangeStreams ( control )
379381 )
380- . pipe ( debounceTime ( mergedConfig . debounceTime ) )
382+ . pipe ( debounce ( value => ( value === NO_DEBOUNCE ? EMPTY : timer ( mergedConfig . debounceTime ) ) ) )
381383 . subscribe ( ( ) => {
382384 const value = this . updateStore ( name , control ) ;
383385 this . updateStorage ( name , value , mergedConfig ) ;
@@ -389,6 +391,28 @@ export class NgFormsManager<FormsState = any> {
389391 return this ;
390392 }
391393
394+ private getValueChangeStreams ( control : AbstractControl ) {
395+ const streams = [ ] ;
396+
397+ if ( control . updateOn === 'blur' ) {
398+ streams . push ( control . valueChanges . pipe ( mapTo ( NO_DEBOUNCE ) ) ) ;
399+ } else {
400+ streams . push ( control . valueChanges ) ;
401+
402+ if ( control instanceof FormGroup ) {
403+ return Object . keys ( control . controls ) . reduce (
404+ ( previous , key ) =>
405+ control . get ( key ) . updateOn === 'blur'
406+ ? [ ...previous , control . get ( key ) . valueChanges . pipe ( mapTo ( NO_DEBOUNCE ) ) ]
407+ : [ ...previous ] ,
408+ streams
409+ ) ;
410+ }
411+ }
412+
413+ return streams ;
414+ }
415+
392416 private removeFromStorage ( ) {
393417 localStorage . setItem ( this . config . merge ( ) . storage . key , JSON . stringify ( this . store . getValue ( ) ) ) ;
394418 }
0 commit comments