@@ -21,6 +21,7 @@ import type {
21
21
InternalFieldData ,
22
22
ValuedNotifyInfo ,
23
23
RuleError ,
24
+ WatchCallBack ,
24
25
} from './interface' ;
25
26
import { HOOK_MARK } from './FieldContext' ;
26
27
import { allPromiseFinish } from './utils/asyncUtil' ;
@@ -93,6 +94,7 @@ export class FormStore {
93
94
setFieldsValue : this . setFieldsValue ,
94
95
validateFields : this . validateFields ,
95
96
submit : this . submit ,
97
+ _init : true ,
96
98
97
99
getInternalHooks : this . getInternalHooks ,
98
100
} ) ;
@@ -114,6 +116,7 @@ export class FormStore {
114
116
getFields : this . getFields ,
115
117
setPreserve : this . setPreserve ,
116
118
getInitialValue : this . getInitialValue ,
119
+ registerWatch : this . registerWatch ,
117
120
} ;
118
121
}
119
122
@@ -141,6 +144,7 @@ export class FormStore {
141
144
142
145
// We will take consider prev form unmount fields.
143
146
// When the field is not `preserve`, we need fill this with initialValues instead of store.
147
+ // eslint-disable-next-line array-callback-return
144
148
this . prevWithoutPreserves ?. map ( ( { key : namePath } ) => {
145
149
nextStore = setValue ( nextStore , namePath , getValue ( initialValues , namePath ) ) ;
146
150
} ) ;
@@ -180,6 +184,28 @@ export class FormStore {
180
184
this . preserve = preserve ;
181
185
} ;
182
186
187
+ // ============================= Watch ============================
188
+ private watchList : WatchCallBack [ ] = [ ] ;
189
+
190
+ private registerWatch : InternalHooks [ 'registerWatch' ] = callback => {
191
+ this . watchList . push ( callback ) ;
192
+
193
+ return ( ) => {
194
+ this . watchList = this . watchList . filter ( fn => fn !== callback ) ;
195
+ } ;
196
+ } ;
197
+
198
+ private notifyWatch = ( namePath : InternalNamePath [ ] = [ ] ) => {
199
+ // No need to cost perf when nothing need to watch
200
+ if ( this . watchList . length ) {
201
+ const values = this . getFieldsValue ( ) ;
202
+
203
+ this . watchList . forEach ( callback => {
204
+ callback ( values , namePath ) ;
205
+ } ) ;
206
+ }
207
+ } ;
208
+
183
209
// ========================== Dev Warning =========================
184
210
private timeoutId : any = null ;
185
211
@@ -498,6 +524,7 @@ export class FormStore {
498
524
this . updateStore ( setValues ( { } , this . initialValues ) ) ;
499
525
this . resetWithFieldInitialValue ( ) ;
500
526
this . notifyObservers ( prevStore , null , { type : 'reset' } ) ;
527
+ this . notifyWatch ( ) ;
501
528
return ;
502
529
}
503
530
@@ -509,16 +536,20 @@ export class FormStore {
509
536
} ) ;
510
537
this . resetWithFieldInitialValue ( { namePathList } ) ;
511
538
this . notifyObservers ( prevStore , namePathList , { type : 'reset' } ) ;
539
+ this . notifyWatch ( namePathList ) ;
512
540
} ;
513
541
514
542
private setFields = ( fields : FieldData [ ] ) => {
515
543
this . warningUnhooked ( ) ;
516
544
517
545
const prevStore = this . store ;
518
546
547
+ const namePathList : InternalNamePath [ ] = [ ] ;
548
+
519
549
fields . forEach ( ( fieldData : FieldData ) => {
520
550
const { name, errors, ...data } = fieldData ;
521
551
const namePath = getNamePath ( name ) ;
552
+ namePathList . push ( namePath ) ;
522
553
523
554
// Value
524
555
if ( 'value' in data ) {
@@ -530,6 +561,8 @@ export class FormStore {
530
561
data : fieldData ,
531
562
} ) ;
532
563
} ) ;
564
+
565
+ this . notifyWatch ( namePathList ) ;
533
566
} ;
534
567
535
568
private getFields = ( ) : InternalFieldData [ ] => {
@@ -573,6 +606,8 @@ export class FormStore {
573
606
574
607
private registerField = ( entity : FieldEntity ) => {
575
608
this . fieldEntities . push ( entity ) ;
609
+ const namePath = entity . getNamePath ( ) ;
610
+ this . notifyWatch ( [ namePath ] ) ;
576
611
577
612
// Set initial values
578
613
if ( entity . props . initialValue !== undefined ) {
@@ -591,8 +626,6 @@ export class FormStore {
591
626
const mergedPreserve = preserve !== undefined ? preserve : this . preserve ;
592
627
593
628
if ( mergedPreserve === false && ( ! isListField || subNamePath . length > 1 ) ) {
594
- const namePath = entity . getNamePath ( ) ;
595
-
596
629
const defaultValue = isListField ? undefined : this . getInitialValue ( namePath ) ;
597
630
598
631
if (
@@ -614,6 +647,8 @@ export class FormStore {
614
647
this . triggerDependenciesUpdate ( prevStore , namePath ) ;
615
648
}
616
649
}
650
+
651
+ this . notifyWatch ( [ namePath ] ) ;
617
652
} ;
618
653
} ;
619
654
@@ -679,6 +714,7 @@ export class FormStore {
679
714
type : 'valueUpdate' ,
680
715
source : 'internal' ,
681
716
} ) ;
717
+ this . notifyWatch ( [ namePath ] ) ;
682
718
683
719
// Dependencies update
684
720
const childrenFields = this . triggerDependenciesUpdate ( prevStore , namePath ) ;
@@ -701,13 +737,15 @@ export class FormStore {
701
737
const prevStore = this . store ;
702
738
703
739
if ( store ) {
704
- this . updateStore ( setValues ( this . store , store ) ) ;
740
+ const nextStore = setValues ( this . store , store ) ;
741
+ this . updateStore ( nextStore ) ;
705
742
}
706
743
707
744
this . notifyObservers ( prevStore , null , {
708
745
type : 'valueUpdate' ,
709
746
source : 'external' ,
710
747
} ) ;
748
+ this . notifyWatch ( ) ;
711
749
} ;
712
750
713
751
private getDependencyChildrenFields = ( rootNamePath : InternalNamePath ) : InternalNamePath [ ] => {
0 commit comments