1
1
import { 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' ;
6
6
import { FormsStore } from './forms-manager.store' ;
7
7
import { Control , ControlFactory , FormKeys , HashMap , UpsertConfig } from './types' ;
8
8
import { Config , NG_FORMS_MANAGER_CONFIG , NgFormsManagerConfig } from './config' ;
9
9
import { isEqual } from './isEqual' ;
10
10
import { deleteControl , findControl , handleFormArray , toStore } from './builders' ;
11
11
12
+ const NO_DEBOUNCE = Symbol ( 'NO_DEBOUNCE' ) ;
13
+
12
14
@Injectable ( { providedIn : 'root' } )
13
15
export class NgFormsManager < FormsState = any > {
14
16
private readonly store : FormsStore < FormsState > ;
@@ -374,10 +376,10 @@ export class NgFormsManager<FormsState = any> {
374
376
}
375
377
376
378
const unsubscribe = merge (
377
- control . valueChanges ,
378
- control . statusChanges . pipe ( distinctUntilChanged ( ) )
379
+ control . statusChanges . pipe ( distinctUntilChanged ( ) ) ,
380
+ ... this . getValueChangeStreams ( control )
379
381
)
380
- . pipe ( debounceTime ( mergedConfig . debounceTime ) )
382
+ . pipe ( debounce ( value => ( value === NO_DEBOUNCE ? EMPTY : timer ( mergedConfig . debounceTime ) ) ) )
381
383
. subscribe ( ( ) => {
382
384
const value = this . updateStore ( name , control ) ;
383
385
this . updateStorage ( name , value , mergedConfig ) ;
@@ -389,6 +391,28 @@ export class NgFormsManager<FormsState = any> {
389
391
return this ;
390
392
}
391
393
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
+
392
416
private removeFromStorage ( ) {
393
417
localStorage . setItem ( this . config . merge ( ) . storage . key , JSON . stringify ( this . store . getValue ( ) ) ) ;
394
418
}
0 commit comments