@@ -7,7 +7,9 @@ import get from "lodash/get";
77import FormContext from "./FormContext" ;
88import { isEmptyValue , deferred } from "./utils" ;
99
10- AsyncValidator . warning = function ( ) { } ;
10+ function noop ( ) { }
11+
12+ AsyncValidator . warning = noop ;
1113
1214export default class Form extends React . Component {
1315 static propTypes = {
@@ -16,6 +18,7 @@ export default class Form extends React.Component {
1618 style : PropTypes . object ,
1719 path2obj : PropTypes . bool ,
1820 defaultFormValue : PropTypes . object ,
21+ getDefaultFieldValue : PropTypes . func ,
1922 formValue : PropTypes . object ,
2023 validators : PropTypes . object ,
2124 validateDelay : PropTypes . number ,
@@ -45,6 +48,7 @@ export default class Form extends React.Component {
4548 validators : { } ,
4649 path2obj : true ,
4750 component : "form" ,
51+ asyncTestDelay : 100 ,
4852 validateDelay : 0 ,
4953 validateTrigger : "none" ,
5054 labelPosition : "left" ,
@@ -75,17 +79,24 @@ export default class Form extends React.Component {
7579 removeField ( field ) {
7680 var idx = this . fields . indexOf ( field ) ;
7781 if ( idx !== - 1 ) {
82+ const name = field . props . name ;
83+
84+ this . state . formError [ name ] = null ;
85+
7886 this . fields . splice ( idx , 1 ) ;
7987 }
8088 }
8189
8290 getValue ( name ) {
91+ const { getDefaultFieldValue } = this . props ;
8392 const path2obj = this . props . path2obj ;
8493 const formValue = this . state . formValue ;
85- if ( path2obj ) {
86- return get ( formValue , name ) ;
87- }
88- return formValue [ name ] ;
94+
95+ const value = path2obj ? get ( formValue , name ) : formValue [ name ] ;
96+
97+ return value === undefined && getDefaultFieldValue
98+ ? getDefaultFieldValue ( name )
99+ : value ;
89100 }
90101
91102 setValue ( name , value , cb ) {
@@ -239,7 +250,9 @@ export default class Form extends React.Component {
239250 return ! ! validatingFields [ name ] ;
240251 }
241252
242- _validateField ( name , callback = ( ) => { } ) {
253+ _validateField ( name , callback ) {
254+ callback = typeof callback === "function" ? callback : noop ;
255+
243256 const value = this . getValue ( name ) ;
244257 const validators = this . getFieldValidator ( name ) ;
245258
@@ -276,6 +289,7 @@ export default class Form extends React.Component {
276289 callback ( errors , value ) ;
277290 } ;
278291
292+ //串行校验
279293 const startCheck = ( ) => {
280294 const validator = validators . shift ( ) ;
281295
@@ -300,9 +314,12 @@ export default class Form extends React.Component {
300314 }
301315
302316 validateField ( name , callback ) {
317+ callback = typeof callback === "function" ? callback : noop ;
318+
319+ const { asyncTestDelay } = this . props ;
303320 const { formError, validatingFields } = this . state ;
321+
304322 //是否异步探测
305- const asyncMaxTime = 100 ; //校验时间小于100ms不算异步
306323 let asyncTimer = setTimeout ( ( ) => {
307324 asyncTimer = null ;
308325 this . setState ( {
@@ -311,7 +328,7 @@ export default class Form extends React.Component {
311328 [ name ] : true
312329 }
313330 } ) ;
314- } , asyncMaxTime ) ;
331+ } , asyncTestDelay ) ;
315332 // let isAsync = true;
316333
317334 this . _validateField ( name , ( errors , value ) => {
@@ -332,28 +349,28 @@ export default class Form extends React.Component {
332349 }
333350 } ,
334351 ( ) => {
335- if ( typeof callback === "function" ) {
336- callback ( errors , value ) ;
337- }
352+ callback ( errors , value ) ;
338353 }
339354 ) ;
340355 } ) ;
341356 }
342357
343- validate ( callback = ( ) => { } ) {
344- const { formValue } = this . state ;
358+ validate ( callback ) {
359+ callback = typeof callback === "function" ? callback : noop ;
360+
361+ const { asyncTestDelay } = this . props ;
362+ const { formValue, formError } = this . state ;
345363 const fields = this . fields ;
346- const validCounter = 0 ;
347- const asyncMaxTime = 100 ; //校验时间小于100ms不算异步
348364 const validatingFields = { } ;
349- const formError = { } ;
350365 const allErrors = [ ] ;
351- let asyncTimer = setTimeout ( ( ) => {
352- asyncTimer = null ;
366+ let validCounter = 0 ;
367+
368+ const updateFormState = ( ) => {
353369 this . setState ( {
370+ formError,
354371 validatingFields
355372 } ) ;
356- } , asyncMaxTime ) ;
373+ } ;
357374
358375 const complete = ( errors , name ) => {
359376 validCounter -- ;
@@ -380,25 +397,48 @@ export default class Form extends React.Component {
380397 } ;
381398
382399 if ( fields . length ) {
400+ //包含多个异步校验的情况下只执行一次
401+ let hasUpdate = false ;
383402 //校验初始化
384403 fields . forEach ( field => {
385404 const name = field . props . name ;
386405 validCounter ++ ;
387406 validatingFields [ name ] = true ;
388- formError [ name ] = null ;
407+
408+ if ( ! ( name in formError ) ) {
409+ formError [ name ] = null ;
410+ }
389411 } ) ;
390412
391413 //开始进行字段校验
392414 fields . forEach ( field => {
393415 const name = field . props . name ;
394416
417+ let isAsyncValidate = false ;
418+ //检测是否异步校验
419+ let asyncTimer = setTimeout ( ( ) => {
420+ isAsyncValidate = true ;
421+ asyncTimer = null ;
422+
423+ if ( hasUpdate ) return ;
424+ hasUpdate = true ;
425+
426+ updateFormState ( ) ;
427+ } , asyncTestDelay ) ;
428+
395429 this . _validateField ( name , errors => {
396430 validatingFields [ name ] = false ;
431+
397432 if ( asyncTimer ) {
398433 clearTimeout ( asyncTimer ) ;
399434 asyncTimer = null ;
400435 }
401436
437+ //异步校验完成后执行刷新动作
438+ if ( isAsyncValidate ) {
439+ updateFormState ( ) ;
440+ }
441+
402442 complete ( errors , name ) ;
403443 } ) ;
404444 } ) ;
@@ -407,7 +447,9 @@ export default class Form extends React.Component {
407447 }
408448 }
409449
410- validateAndScroll ( callback = ( ) => { } ) {
450+ validateAndScroll ( callback ) {
451+ callback = typeof callback === "function" ? callback : noop ;
452+
411453 this . validate ( ( errors , formValue ) => {
412454 if ( errors ) {
413455 const fields = this . fields ;
0 commit comments