Skip to content

Commit 3c62014

Browse files
committed
Modified examples/demos/demo1.js
Modified src/Form.js Modified src/FormItem.js
1 parent d176a1f commit 3c62014

File tree

3 files changed

+126
-51
lines changed

3 files changed

+126
-51
lines changed

examples/demos/demo1.js

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ import { Form, FormItem, NativeField } from "../../src/index";
44

55
function Input(props) {
66
return (
7-
<input
7+
<NativeField
88
{...props}
99
className=""
10+
type="text"
1011
style={{
1112
height: 32,
1213
padding: "4px 7px"
1314
}}
14-
></input>
15+
component="input"
16+
/>
1517
);
1618
}
1719

@@ -51,13 +53,11 @@ export default class DEMO extends Component {
5153

5254
getRules() {
5355
return {
54-
"info.address": {
55-
type: "email",
56-
message: "emial 错误..."
56+
"info.address": function() {
57+
return false;
5758
},
58-
name: {
59-
required: true,
60-
message: "必填"
59+
name: function(value) {
60+
return value === "" ? "不能为空" : true;
6161
}
6262
// name(rule, value, callback) {
6363
// setTimeout(() => {
@@ -77,11 +77,12 @@ export default class DEMO extends Component {
7777
return (
7878
<div>
7979
<Form
80+
getDefaultFieldValue={() => ""}
8081
ref={form => (this.form = form)}
8182
formValue={formValue}
8283
onChange={formValue => this.setState({ formValue })}
8384
onSubmit={this.onSubmit}
84-
rules={this.getRules()}
85+
validators={this.getRules()}
8586
inline
8687
validateTrigger="blur"
8788
>
@@ -122,7 +123,6 @@ export default class DEMO extends Component {
122123
<FormItem
123124
name="name"
124125
labelWidth={100}
125-
labelPosition="right"
126126
label="姓名"
127127
inline
128128
>
@@ -167,12 +167,58 @@ export default class DEMO extends Component {
167167
<FormItem name="info.address" label="地址">
168168
<NativeField component="input" />
169169
</FormItem>
170-
<FormItem name="info.list[0]" label="L1">
170+
<FormItem
171+
name="info.list[0]"
172+
label="L1"
173+
validator={value => {
174+
return new Promise(
175+
(resolve, reject) => {
176+
setTimeout(
177+
value
178+
? resolve
179+
: () =>
180+
reject(
181+
"校验失败"
182+
),
183+
2000
184+
);
185+
}
186+
);
187+
}}
188+
>
171189
<NativeField component="input" />
172190
</FormItem>
173-
<FormItem name="info.list[1]" label="L2">
191+
<div>
192+
{form.isValidatingField("info.list[0]")
193+
? "数据校验中..."
194+
: null}
195+
</div>
196+
<FormItem
197+
name="info.list[1]"
198+
label="L2"
199+
validator={value => {
200+
return new Promise(
201+
(resolve, reject) => {
202+
setTimeout(
203+
value
204+
? resolve
205+
: () =>
206+
reject(
207+
"校验失败"
208+
),
209+
1000
210+
);
211+
}
212+
);
213+
}}
214+
>
174215
<NativeField component="input" />
175216
</FormItem>
217+
<div>
218+
{form.isValidatingField("info.list[1]")
219+
? "数据校验中..."
220+
: null}
221+
</div>
176222
<FormItem name="info.country" label="国籍">
177223
<NativeField component="select">
178224
<option value="中国">中国</option>

src/Form.js

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import get from "lodash/get";
77
import FormContext from "./FormContext";
88
import { isEmptyValue, deferred } from "./utils";
99

10-
AsyncValidator.warning = function() {};
10+
function noop() {}
11+
12+
AsyncValidator.warning = noop;
1113

1214
export 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;

src/FormItem.js

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,6 @@ export default class FormItem extends React.Component {
6161
form.removeField(this);
6262
}
6363

64-
isRequired() {
65-
const { form } = this.context;
66-
const { name } = this.props;
67-
let rules = form.getFieldRules(name);
68-
let isRequired = false;
69-
70-
if (rules && rules.length) {
71-
isRequired = rules.some(rule => rule.required);
72-
}
73-
74-
return isRequired;
75-
}
76-
7764
_validateTimer = null;
7865

7966
getValidateTrigger() {
@@ -163,15 +150,15 @@ export default class FormItem extends React.Component {
163150
return {
164151
value: this.getValue(),
165152
...customProps,
166-
onChange: (value, e) => {
153+
onChange: value => {
167154
if (normalize) {
168155
value = normalize(value);
169156
}
170157

171-
onChange && onChange(value, e);
172-
customProps.onChange && customProps.onChange(value, e);
158+
onChange && onChange(value);
159+
customProps.onChange && customProps.onChange(value);
173160

174-
this.onFieldChange(value, e);
161+
this.onFieldChange(value);
175162
},
176163
onBlur: e => {
177164
onBlur && onBlur(e);
@@ -229,7 +216,7 @@ export default class FormItem extends React.Component {
229216
alignItems !== "center",
230217
[`${prefixCls}-error`]: error,
231218
[`${prefixCls}-validating`]: validating,
232-
[`${prefixCls}-required`]: this.isRequired() || required,
219+
[`${prefixCls}-required`]: required,
233220
[`${prefixCls}-with-help`]: help,
234221
[`${className}`]: className
235222
})}

0 commit comments

Comments
 (0)