8
8
getParams ,
9
9
setIn ,
10
10
getIn ,
11
+ deleteIn ,
11
12
mapValidateRules ,
12
13
} from './utils' ;
13
14
@@ -29,7 +30,9 @@ class Field {
29
30
this . fieldsMeta = { } ;
30
31
this . cachedBind = { } ;
31
32
this . instance = { } ;
32
- this . initValue = options . values || { } ;
33
+ // holds constructor values. Used for setting field defaults on init if no other value or initValue is passed.
34
+ // Also used caching values when using `parseName: true` before a field is initialized
35
+ this . values = options . values || { } ;
33
36
34
37
this . options = Object . assign (
35
38
{
@@ -89,6 +92,8 @@ class Field {
89
92
getValueFromEvent = null ,
90
93
autoValidate = true ,
91
94
} = fieldOption ;
95
+ const { parseName } = this . options ;
96
+
92
97
const originalProps = Object . assign ( { } , props , rprops ) ;
93
98
const defaultValueName = `default${ valueName [ 0 ] . toUpperCase ( ) } ${ valueName . slice (
94
99
1
@@ -100,11 +105,10 @@ class Field {
100
105
defaultValue = initValue ;
101
106
} else if ( originalProps [ defaultValueName ] ) {
102
107
defaultValue = originalProps [ defaultValueName ] ;
103
- } else if ( this . options . parseName ) {
104
- defaultValue = getIn ( this . initValue , name ) ;
108
+ } else if ( parseName ) {
109
+ defaultValue = getIn ( this . values , name ) ;
105
110
} else {
106
- defaultValue =
107
- ( this . initValue && this . initValue [ name ] ) || undefined ;
111
+ defaultValue = ( this . values && this . values [ name ] ) || undefined ;
108
112
}
109
113
110
114
Object . assign ( field , {
@@ -125,6 +129,11 @@ class Field {
125
129
if ( ! ( 'value' in field ) ) {
126
130
field . value = defaultValue ;
127
131
}
132
+ if ( parseName && ! getIn ( this . values , name ) ) {
133
+ this . values = setIn ( this . values , name , field . value ) ;
134
+ } else if ( ! parseName && ! this . values [ name ] ) {
135
+ this . values [ name ] = field . value ;
136
+ }
128
137
129
138
// Component props
130
139
const inputProps = {
@@ -201,6 +210,12 @@ class Field {
201
210
? field . getValueFromEvent . apply ( this , others )
202
211
: getValueFromEvent ( e ) ;
203
212
213
+ if ( this . options . parseName ) {
214
+ this . values = setIn ( this . values , name , field . value ) ;
215
+ } else {
216
+ this . values [ name ] = field . value ;
217
+ }
218
+
204
219
this . _resetError ( name ) ;
205
220
206
221
// validate while onChange
@@ -248,14 +263,19 @@ class Field {
248
263
const cache = this . fieldsMeta [ name ] ;
249
264
this . _setCache ( name , key , cache ) ;
250
265
// after destroy, delete data
251
- delete this . fieldsMeta [ name ] ;
252
266
delete this . instance [ name ] ;
267
+ this . remove ( name ) ;
253
268
return ;
254
269
}
255
270
256
271
// 2. _saveRef(B, ref) (eg: same name but different compoent may be here)
257
272
if ( autoUnmount && ! this . fieldsMeta [ name ] ) {
258
273
this . fieldsMeta [ name ] = this . _getCache ( name , key ) ;
274
+ this . setValue (
275
+ name ,
276
+ this . fieldsMeta [ name ] && this . fieldsMeta [ name ] . value ,
277
+ false
278
+ ) ;
259
279
}
260
280
261
281
// only one time here
@@ -312,45 +332,39 @@ class Field {
312
332
}
313
333
314
334
getValue ( name ) {
315
- const field = this . _get ( name ) ;
316
-
317
- if ( field && 'value' in field ) {
318
- return field . value ;
335
+ if ( this . options . parseName ) {
336
+ return getIn ( this . values , name ) ;
319
337
}
320
-
321
- return undefined ;
338
+ return this . values [ name ] ;
322
339
}
323
340
324
341
/**
325
342
* 1. get values by names.
326
- * 2. ignore disabled value.
343
+ * 2. If no names passed, return shallow copy of `field.values`
327
344
* @param {Array } names
328
345
*/
329
346
getValues ( names ) {
330
- const fields = names || this . getNames ( ) ;
331
- let allValues = { } ;
347
+ const allValues = { } ;
348
+
349
+ if ( names && names . length ) {
350
+ names . forEach ( name => {
351
+ allValues [ name ] = this . getValue ( name ) ;
352
+ } ) ;
353
+ } else {
354
+ Object . assign ( allValues , this . values ) ;
355
+ }
332
356
333
- fields . forEach ( f => {
334
- if ( f . disabled ) {
335
- return ;
336
- }
337
- if ( ! this . options . parseName ) {
338
- allValues [ f ] = this . getValue ( f ) ;
339
- } else {
340
- allValues = setIn ( allValues , f , this . getValue ( f ) ) ;
341
- }
342
- } ) ;
343
357
return allValues ;
344
358
}
345
359
346
360
setValue ( name , value , reRender = true ) {
347
361
if ( name in this . fieldsMeta ) {
348
362
this . fieldsMeta [ name ] . value = value ;
363
+ }
364
+ if ( this . options . parseName ) {
365
+ this . values = setIn ( this . values , name , value ) ;
349
366
} else {
350
- // if not exist, then new one
351
- this . fieldsMeta [ name ] = {
352
- value,
353
- } ;
367
+ this . values [ name ] = value ;
354
368
}
355
369
reRender && this . _reRender ( ) ;
356
370
}
@@ -361,11 +375,22 @@ class Field {
361
375
this . setValue ( name , fieldsValue [ name ] , false ) ;
362
376
} ) ;
363
377
} else {
378
+ // NOTE: this is a shallow merge
379
+ // Ex. we have two values a.b.c=1 ; a.b.d=2, and use setValues({a:{b:{c:3}}}) , then because of shallow merge a.b.d will be lost, we will get only {a:{b:{c:3}}}
380
+ this . values = Object . assign ( { } , this . values , fieldsValue ) ;
364
381
const fields = this . getNames ( ) ;
365
382
fields . forEach ( name => {
366
- const value = getIn ( fieldsValue , name ) ;
383
+ const value = getIn ( this . values , name ) ;
367
384
if ( value !== undefined ) {
368
- this . setValue ( name , value , false ) ;
385
+ // copy over values that are in this.values
386
+ this . fieldsMeta [ name ] . value = value ;
387
+ } else {
388
+ // if no value then copy values from fieldsMeta to keep initialized component data
389
+ this . values = setIn (
390
+ this . values ,
391
+ name ,
392
+ this . fieldsMeta [ name ] . value
393
+ ) ;
369
394
}
370
395
} ) ;
371
396
}
@@ -586,9 +611,12 @@ class Field {
586
611
let changed = false ;
587
612
588
613
const names = ns || Object . keys ( this . fieldsMeta ) ;
614
+
615
+ if ( ! ns ) {
616
+ this . values = { } ;
617
+ }
589
618
names . forEach ( name => {
590
619
const field = this . _get ( name ) ;
591
- this . getValue ( name ) ;
592
620
if ( field ) {
593
621
changed = true ;
594
622
@@ -598,6 +626,12 @@ class Field {
598
626
delete field . errors ;
599
627
delete field . rules ;
600
628
delete field . rulesMap ;
629
+
630
+ if ( this . options . parseName ) {
631
+ this . values = setIn ( this . values , name , field . value ) ;
632
+ } else {
633
+ this . values [ name ] = field . value ;
634
+ }
601
635
}
602
636
} ) ;
603
637
@@ -641,11 +675,20 @@ class Field {
641
675
if ( typeof ns === 'string' ) {
642
676
ns = [ ns ] ;
643
677
}
678
+ if ( ! ns ) {
679
+ this . values = { } ;
680
+ }
681
+
644
682
const names = ns || Object . keys ( this . fieldsMeta ) ;
645
683
names . forEach ( name => {
646
684
if ( name in this . fieldsMeta ) {
647
685
delete this . fieldsMeta [ name ] ;
648
686
}
687
+ if ( this . options . parseName ) {
688
+ this . values = deleteIn ( this . values , name ) ;
689
+ } else {
690
+ delete this . values [ name ] ;
691
+ }
649
692
} ) ;
650
693
}
651
694
@@ -660,12 +703,14 @@ class Field {
660
703
return ;
661
704
}
662
705
706
+ // regex to match field names in the same target array
663
707
const reg = keyMatch . replace ( '{index}' , '(\\d+)' ) ;
664
708
const keyReg = new RegExp ( `^${ reg } $` ) ;
665
709
666
710
let list = [ ] ;
667
711
const names = this . getNames ( ) ;
668
712
names . forEach ( n => {
713
+ // is name in the target array?
669
714
const ret = keyReg . exec ( n ) ;
670
715
if ( ret ) {
671
716
const index = parseInt ( ret [ 1 ] ) ;
@@ -684,12 +729,20 @@ class Field {
684
729
if ( list . length > 0 && list [ 0 ] . index === startIndex + 1 ) {
685
730
list . forEach ( l => {
686
731
const n = keyMatch . replace ( '{index}' , l . index - 1 ) ;
687
- this . fieldsMeta [ n ] = this . fieldsMeta [ l . name ] ;
732
+ const v = this . getValue ( l . name ) ;
733
+ this . setValue ( n , v , false ) ;
688
734
} ) ;
735
+ this . remove ( list [ list . length - 1 ] . name ) ;
689
736
690
- delete this . fieldsMeta [ list [ list . length - 1 ] . name ] ;
737
+ let parentName = keyMatch . replace ( '.{index}' , '' ) ;
738
+ parentName = parentName . replace ( '[{index}]' , '' ) ;
739
+ const parent = this . getValue ( parentName ) ;
691
740
692
- this . _reRender ( ) ;
741
+ if ( parent ) {
742
+ // if parseName=true then parent is an Array object but does not know an element was removed
743
+ // this manually decrements the array length
744
+ parent . length -- ;
745
+ }
693
746
}
694
747
}
695
748
0 commit comments