Form๊ณผ ๊ฐ์ ์ผ๋ จ์ ๊ตฌ์ฑ ์์๋ฅผ ์ ๊ณตํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
์์์ ๊ฐ ํ๋๋ ์ ์ถ ์ ์ ๋ค์ ํ์ธํด์ผ ํ๋ฏ๋ก validateFieldsAndScroll
. ๊ทธ๋ฌ๋ ๋ฐ๊ฒฌ์ ํจ๊ณผ๊ฐ ์์์ต๋๋ค.
๋๋ฒ๊น
ํ ์ง์ ๋ ํ๋ ์ธํธ๊ฐ ํจ์์ ์ ๋ฌ๋๋ฉด ์ ์ฉํ ์ ์์์ ๋ฐ๊ฒฌํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด ํ๋ ์ธํธ์ ๋ณด์กฐ ๊ฒ์ฆ์ ์ํ ๊ฒ์ฆ ๊ท์น์์ validator
์ ์ฌ์ฉ์ ์ง์ ํ๋ ํญ๋ชฉ์ด ํฌํจ๋์ด ์๋ ํ ์ ์ฒด validateFields
๋ฐฉ๋ฒ์ ์ ์ฉ๋์ง ์์ต๋๋ค.
๊ฒฐ๊ตญ, ์ฒ์์ ํด๋น validator
์ฝ๋ฐฑ์์ ํญ์ callback()
๋ฅผ ๋ฐํํ์ง ์์๊ธฐ ๋๋ฌธ์ด๋ผ๋ ๊ฒ์ ์์์ต๋๋ค. ์ฒ์์ ์ฐ์ง ์๊ณ ๋จ์ผ ์
๋ ฅ์ ๋ํ ๊ฒ์
๋๋ค. ์ผ๋ฐ ๊ฒ์ฌ). ์ถ๊ฐํ๊ณ ๋๋ฉด ๊ด์ฐฎ์ต๋๋ค.
์ค๋กํฉ๋๋ค. ๋ฒ๊ทธ์ธ๊ฐ์? ์ด ๋ฌธ์์์ ์ง์ ๋์ง ์๊ธฐ ๋๋ฌธ์ validator
๋ฐํํด์ผํฉ๋๋ค callback()
.
callback
๋ฅผ ๋ฐํํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ฌธ์์์ ๊ฐ๋ฐ์์๊ฒ ์๊ธฐ์ํค๊ฑฐ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์ ํ ์ ์์ต๋๋ค.
handleSubmit = (e) => {
e.preventDefault()
const { onSubmit } = this.props
const { validateFieldsAndScroll, getFieldsValue, resetFields } = this.props.form
validateFieldsAndScroll((err, values) => {
if (!err) {
onSubmit(getFieldsValue())
}
})
}
handleConfirmPassword = (rule, value, callback) => {
const { getFieldValue } = this.props.form
if (value && value !== getFieldValue('newPassword')) {
callback('ไธคๆฌก่พๅ
ฅไธไธ่ด๏ผ')
}
// Note: ๅฟ
้กปๆปๆฏ่ฟๅไธไธช callback๏ผๅฆๅ validateFieldsAndScroll ๆ ๆณๅๅบ
callback()
}
render()
<FormItem
{...formItemLayout}
label="็กฎ่ฎคๅฏ็ "
>
{
getFieldDecorator('confirmPassword', {
rules: [{
required: true,
message: '่ฏทๅๆฌก่พๅ
ฅไปฅ็กฎ่ฎคๆฐๅฏ็ ',
}, {
validator: this.handleConfirmPassword
}],
})(<Input type="password" />)
}
</FormItem>
์ค๊ณ: https://github.com/yiminghe/async-validator/
BTW, callback
๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฆฌ์ง ์์ผ๋ฉด async-validator๊ฐ ๋น๋๊ธฐ ํ๋ก์์ ๊ฐ ์ข
๋ฃ๋์์์ ์ด๋ป๊ฒ ์ ์ ์์ต๋๊น?
๋๋ ๋ถํํ๋ค https://www.zhihu.com/question/33629737/answer/150154145
์ฐ๋ฆฌ์ ์คํ ์์ค ์์น ์ค ํ๋๊ฐ ๋ฌผ๊ณผ ํ์ ๋ฎ๋ ๊ฒ์ด๋ผ๋ ๋ฌธ์๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
๋ฌธ์๊ฐ ์ ๋ฐ์ดํธ๋์์ต๋๋ค.
์๋
ํ์ธ์, ์ด ์ฌ์ฉ๋ฒ์ ์์
์์๋ง ์ธ ์ ์๋์?
์์ ํ ๊ธฐ๋ฅ์ ์ธ ๋ฐฉ์์ผ๋ก React Component๋ฅผ ์์ฑํ ์ ์์ต๋๊น?๊ทธ๋ ๋ค๋ฉด ์ด๋ค ๊ฒฝ์ฐ๊ฐ ์์ต๋๊น?
์ด API ๋์์ธ์ ์ ๋ง ์ด์ค๋ฝ๋ค์.. ํน์ ์ฒดํฌ๋ฐ์ค๊ฐ ์ ํ๋์๋์ง ํ์ธํ๊ณ ์ถ์ ์๊ฐ์ด ๋ญ๋๋ค.
rules: [
{
message: 'You need to agree to our terms to sign up.',
validator: (rule, value, cb) => (value === true ? cb() : cb(true)),
},
],
๊ทธ๋ฆฌ๊ณ ์ฝ๋ฐฑ์๊ฒ ์ฃผ์ด์ง ์ฒซ ๋ฒ์งธ ๋งค๊ฐ ๋ณ์๋์ ์ค๋ณต ์ค๋ฅ ๋ฉ์์ง์
๋๋ค message
๊ฐ ๊ธด ์๋ฌด๊ฒ๋ ๋ฐํ ํ ๊ฒ์ผ๋ก ๋ณด์ด์ง๋ง ( message
์ฌ์ฉ๋ฉ๋๋ค, ๊ทธ๊ฒ์ด ์ ์ฉ๋์ด์ผํ๋ค message
์ค๋ฅ ๋ฉ์์ง).
๋๋ถ๋ถ์ ์ฌ์ฉ์๊ฐ ์์ํ๋ ์ฌ์ฉ๋ฒ์ true
๋๋ false
๋ฅผ ์ง์ ๋ฐํํ์ฌ ์ณ๊ณ ๊ทธ๋ฆ์ ๊ฒฐ์ ํ๋ ๊ฒ์
๋๋ค.
rules: [
{
message: 'You need to agree to our terms to sign up.',
validator: (rule, value, cb) => value === true,
},
],
์ฌ์ฉ ๊ฐ๋ฅํ์ง๋ง ์ด API๋ฅผ ์ต์ ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ฆ, https://github.com/yiminghe/async-validator/ ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด์ง๋ง ANT๋ ์ฌ๊ธฐ์์ ์๋ฃํ ์ ์์ผ๋ฉฐ ํธ์ถ ์ ์บก์ํํ ์ ์์ต๋๋ค.
@neekey ๋ async-validator์ ํธํ๋๋ PR์ ์ ์ถํ ์ ์์ต๋๋ค.
@nekey ์ด ์ด์ํ ์ธํฐํ์ด์ค๋ ๋ค์์ ๋ฌ์ฑํฉ๋๋ค.
๋ ์ข์ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
<Row>
<Col span={24} key={"method"}>
<FormItem {...formItemMethodLayout} label="่ฏทๆฑๆนๆณ">
{getFieldDecorator("method", {
initialValue: this.state.data.method,
validateTrigger: "onChange",
rules: [{
required: true,
message: `่ฏท้ๆฉ่ฏทๆฑๆนๆณ`
}, {
//validator: this.state.checkUnique ? this.checkConfirmMethod.bind(this) : (rule, value, callback) => {callback();},
validator: (่ฟๅฆไฝๅคๆญๅฝๅ็ปไปถๆฏๅฆๅผๅงๆ ก้ชไบ) ๏ผ
this.checkConfirmMethod.bind(this) : (ๅฆๆไธๆฏๅฝๅ็ปไปถๅผๅงๆ ก้ช๏ผๅฐฑ่ฐ็จๅ
ถไปๅฝๆฐ),
}]
})(
<Select placeholder={"่ฏท้ๆฉ่ฏทๆฑๆนๆณ"} onChange={::this.handleChange.bind(this)}>
{this.state.apiRequestMethodSelect}
</Select>
)}
</FormItem>
</Col>
</Row
๊ธฐ๋ฅ๊ฒ์ฆ ๋ง๋ ๋๋ง๋ค ํ๋ฒ์ฉ ๋ณด๋ฌ ์์ผ๊ฒ ์ต๋๋ค..๊ธฐ์ตํ๊ธฐ ์ ๋ง ํ๋๋ค์
startNumValidator = (rule, value, callback) => {
const { exportDataCount } = this.props;
const reg = /^[1-9][0-9]*$/;
let errors = [];
if (!reg.test(value) || value > exportDataCount) {
errors.push(new Error('illegal value'));
}
callback(errors);
}
ํตํฉ ์ฝ๋ฐฑ ์ค๋ฅ ์๋๊ฐ์? ์๋นํ ํฉ๋ฆฌ์ ์ผ๋ก ๋๊ปด์ง๋๋ค.
antd์ ์ ๋ฒ์ ์ด ๋น๋๊ธฐ์๊ณผ ๋๊ธฐ์ ๊ฒ์ฆ์ ๊ตฌ๋ถํ๊ธฐ ์์ํ๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. validator(๋๊ธฐ์) asyncValidator(๋น๋๊ธฐ์)
์์ฒญ ํ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ฐํ๋ ์ฝ๋ฐฑ์์ ์ด ๋ฉ์์ง ํ๋กฌํํธ๋ฅผ ํธ์ถํ๋ ๋ฐฉ๋ฒ
๊ท์น์์ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ง์ ํ์ธ์ ์ํํ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
validateFunc = (๊ท์น, ๊ฐ, ์ฝ๋ฐฑ) => {
์ฌ์ค์ด๋ฉด) {
console.log(11);
callback('์ค๋ฅ ๋ฉ์์ง');
๋ฐํ;
}
์ฝ๋ฐฑ();
};
ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ ํ์ธ ๊ฒฐ๊ณผ 'Error message'๋ฅผ ํ์ํ๊ณ ์ถ์๋ฐ ์ฝ๋ฐฑ ์คํ ํ ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ 'Error message'๊ฐ ์ถ๋ ฅ๋์ง ์๊ณ ์ฝ์์ ์ถ๋ ฅ๋๋ ์ด์ ๋?
ๅจๅฏนๅบ็FormItem็ปไปถไธๆพ็คบ
์ ๋
ผ๋ฆฌ๋ ์ด๋ป๊ฒ ์์ฑํฉ๋๊น?
@neekey ๋ async-validator์ ํธํ๋๋ PR์ ์ ์ถํ ์ ์์ต๋๋ค.
๋๊ตฐ๊ฐ ๊ทธ๊ฒ์ ์ธ๊ธํ๋ค๊ณ yminghe๊ฐ ๋งํ์ต๋๋ค .
ๅจๅฏนๅบ็FormItem็ปไปถไธๆพ็คบ
์ ๋ ผ๋ฆฌ๋ ์ด๋ป๊ฒ ์์ฑํฉ๋๊น?
์ปค์คํ
๊ฒ์ฆ ๋ฐฉ์์ ๋ณ๊ฒฝํ์ฌ onFieldsChange()์์ ํ๋จํ๋๋ฐ, ์ปค์คํ
๋ฃฐ์ด ์ถฉ์กฑ๋์ง ์์ผ๋ฉด ์๋ฌ๊ฐ ์ง์ ๋ณ๊ฒฝ๋๊ณ , ์ปจํธ๋กค์ ์๋ฌ ์ ๋ณด๊ฐ ํ์๋ฉ๋๋ค.
onFieldsChange(props, changedFields) {
const { dispatch, detail } = props;
const finalChangedFields = { ...changedFields };
// ๆ ก้ชๆถ้ดๅคงๅฐๆฏๅฆ็ฌฆๅ่งๅ
if (
_.has(changedFields, 'currentDate') &&
detail?.targetDate &&
compareCurrentTimeEarlierThanTargetTime(
finalChangedFields.currentDate,
detail?.targetDate
)
) {
finalChangedFields.currentDate.errors = [
{
message: 'current Date should be latter than target Date',
field: 'currentDate',
},
];
}
dispatch({
type: 'controllerModel/saveDetail',
payload: {
changedFields: finalChangedFields,
data: detail,
},
});
}
ํ์ธ์ ํต๊ณผํ ํ ๋ค์ ๋ฉ์์ง๊ฐ ์ฌ๋ผ์ง์ง ์๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
์ง๋ฌธํ์ญ์์ค. ์ด ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๋ ํ์ด์ง๊ฐ ๋ก๋๋ ๋ ํ์ธ์ ์ํํ์ง ์์ ์ ์์ต๋๊น?
@neekey
์ฝ๋ฐฑ ๊ธฐ๋ฅ์
<Form>
<Form.Item ...>
{getFieldDecorator('name', {validator: (rule, value, callback) => setTimeout(callback(), 1000)})(
<Input placeholder="name" />
)}
</Form.Item>
....
setTimeout์ด ์คํ๋๊ธฐ ์ ์ ์ ์ฒด ๊ตฌ์ฑ ์์๊ฐ ๋ง์ดํธ ํด์ ๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์๊ฐ ์ด๊ณผ๊ฐ ๋ฐ์ํ๊ณ ์ฝ๋ฐฑ์ด ์์๋๊ณ
@jiufengdadi
์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
๋ด ์๋ฃจ์
์ undefined
์ callback
์
๋๋ค. callback
์ ์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๊ฐ ๋น ๋ฐฐ์ด์ด๋ฉด ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๊ฐ ํต๊ณผํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋งค๊ฐ๋ณ์์ ๊ธฐ๋ณธ๊ฐ์ ์ค์ ํ๋ฏ๋ก undefined
๋ ์๋ํฉ๋๋ค.
callback
์ ์: L146
๋ด ์ฌ์ฉ์ ์ง์ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ํต๊ณผ๋ ํ async-validator: [""]๊ฐ ๋ํ๋๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
๋ ๊ฐ์ ๊ฒ์ฌ๊ฐ ์๋ ๊ฒฝ์ฐ ์ฒซ ๋ฒ์งธ ๊ฒ์ฌ๋ ์คํจํฉ๋๋ค. ์ด์ ๋ ๋ฌด์์
๋๊น?
```
๊ท์น: [
{
ํ์: ์ฌ์ค,
๋ฉ์์ง: '์ ํ๋ฒํธ๋ฅผ ์
๋ ฅํ์ธ์',
},
{
์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ: (๊ท์น, ๊ฐ, ์ฝ๋ฐฑ) => {
๋
ธ๋ ฅํ๋ค {
if (this.props.form.getFieldValue('์ ๋์ฌ') == 86 && ๊ฐ) {
์์ ๋ฑ๋ก = /^1d{10}$/;
if (!reg.test(๊ฐ)) {
throw new Error('๋ญ๊ฐ ์๋ชป๋์์ต๋๋ค!');
}
}
} ์ก๊ธฐ(์ค๋ฅ) {
์ฝ๋ฐฑ(์ค๋ฅ);
}
},
๋ฉ์์ง: '์ ํจํ ํด๋ํฐ ๋ฒํธ๋ฅผ ์
๋ ฅํ์ธ์',
},
],
rules: [
{
required: true,
message: '่ฏท่พๅ
ฅๆๆบๅท',
},
{
validator: (rule, value, callback) => {
try {
if (this.props.form.getFieldValue('prefix') == 86 && value) {
const reg = /^1\d{10}$/;
if (!reg.test(value)) {
throw new Error('Something wrong!');
}
}
} catch (err) {
callback(err);
return // +
}
callback() // +
},
message: '่ฏท่พๅ
ฅๆๆๆๆบๅท',
},
],
๊ท์น์์ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ง์ ํ์ธ์ ์ํํ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
validateFunc = (๊ท์น, ๊ฐ, ์ฝ๋ฐฑ) => {
์ฌ์ค์ด๋ฉด) {
console.log(11);
callback('์ค๋ฅ ๋ฉ์์ง');
๋ฐํ;
}
์ฝ๋ฐฑ();
};
ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ ํ์ธ ๊ฒฐ๊ณผ 'Error message'๋ฅผ ํ์ํ๊ณ ์ถ์๋ฐ ์ฝ๋ฐฑ ์คํ ํ ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ 'Error message'๊ฐ ์ถ๋ ฅ๋์ง ์๊ณ ์ฝ์์ ์ถ๋ ฅ๋๋ ์ด์ ๋?
๊ท์น์์ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ง์ ํ์ธ์ ์ํํ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
validateFunc = (๊ท์น, ๊ฐ, ์ฝ๋ฐฑ) => {
์ฌ์ค์ด๋ฉด) {
console.log(11);
callback('์ค๋ฅ ๋ฉ์์ง');
๋ฐํ;
}
์ฝ๋ฐฑ();
};
ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ ํ์ธ ๊ฒฐ๊ณผ 'Error message'๋ฅผ ํ์ํ๊ณ ์ถ์๋ฐ ์ฝ๋ฐฑ ์คํ ํ ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ 'Error message'๊ฐ ์ถ๋ ฅ๋์ง ์๊ณ ์ฝ์์ ์ถ๋ ฅ๋๋ ์ด์ ๋?
๋น์ ์ ๊ทธ๊ฒ์ ํด๊ฒฐ ํ์ต๋๊น, ๊ฐ์ ์ํฉ์ด ๋ฐ์ํ์ต๋๋ค
rules: [ { required: true, message: '่ฏท่พๅ ฅๆๆบๅท', }, { validator: (rule, value, callback) => { try { if (this.props.form.getFieldValue('prefix') == 86 && value) { const reg = /^1\d{10}$/; if (!reg.test(value)) { throw new Error('Something wrong!'); } } } catch (err) { callback(err); return // + } callback() // + }, message: '่ฏท่พๅ ฅๆๆๆๆบๅท', }, ],
๋ฉ์์ง ํ๋กฌํํธ๊ฐ ๋ฐ๋ณต๋ฉ๋๊น? ์ด์ ์ ์ฌํ 'ํด๋์ ํ ๋ฒํธ๋ฅผ ์ ๋ ฅํ์ญ์์ค. ์ ํจํ ํด๋์ ํ ๋ฒํธ๋ฅผ ์ ๋ ฅํ์ญ์์ค.'
rules: [ { required: true, message: '่ฏท่พๅ ฅๆๆบๅท', }, { validator: (rule, value, callback) => { try { if (this.props.form.getFieldValue('prefix') == 86 && value) { const reg = /^1\d{10}$/; if (!reg.test(value)) { throw new Error('Something wrong!'); } } } catch (err) { callback(err); return // + } callback() // + }, message: '่ฏท่พๅ ฅๆๆๆๆบๅท', }, ],
๋ฉ์์ง ํ๋กฌํํธ๊ฐ ๋ฐ๋ณต๋ฉ๋๊น? ์ด์ ์ ์ฌํ 'ํด๋์ ํ ๋ฒํธ๋ฅผ ์ ๋ ฅํ์ญ์์ค. ์ ํจํ ํด๋์ ํ ๋ฒํธ๋ฅผ ์ ๋ ฅํ์ญ์์ค.'
ํ์ง ์์ ๊ฒ์ด๋ค
๋ค์๊ณผ ๊ฐ์ด ํ์ญ์์ค
๋นจ๊ฐ์ ์ฒดํฌ๊ฐ ์ฌ๋ผ์ง์ง ์์ ์ด์ ๋ ๋ฌด์์ ๋๊น? ? ? ์ฌ์์ ์ถฉ์กฑํ๋ ์ด๋ฌํ ์ข ๋ฅ์ ์ํธ ์ํฅ ๊ฒ์ฆ์ ์ํํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ ๋๊น? ? ?
๊ท์น์ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ์ ์ฝ๋ฐฑ์ ์ฑ๊ณต ์ฌ๋ถ์ ๊ด๊ณ์์ด ํธ์ถ๋์ด์ผ ํ๋ฉฐ ๋งค๊ฐ๋ณ์๊ฐ ์ ๋ฌ๋์ง ์๋๋ค๋ ์ฐจ์ด์ ์ด ์์ต๋๋ค.
๊ท์น์์ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ง์ ํ์ธ์ ์ํํ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
validateFunc = (๊ท์น, ๊ฐ, ์ฝ๋ฐฑ) => {
์ฌ์ค์ด๋ฉด) {
console.log(11);
callback('์ค๋ฅ ๋ฉ์์ง');
๋ฐํ;
}
์ฝ๋ฐฑ();
};
ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ ํ์ธ ๊ฒฐ๊ณผ 'Error message'๋ฅผ ํ์ํ๊ณ ์ถ์๋ฐ ์ฝ๋ฐฑ ์คํ ํ ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ 'Error message'๊ฐ ์ถ๋ ฅ๋์ง ์๊ณ ์ฝ์์ ์ถ๋ ฅ๋๋ ์ด์ ๋?๊ท์น์์ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ง์ ํ์ธ์ ์ํํ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
validateFunc = (๊ท์น, ๊ฐ, ์ฝ๋ฐฑ) => {
์ฌ์ค์ด๋ฉด) {
console.log(11);
callback('์ค๋ฅ ๋ฉ์์ง');
๋ฐํ;
}
์ฝ๋ฐฑ();
};
ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ ํ์ธ ๊ฒฐ๊ณผ 'Error message'๋ฅผ ํ์ํ๊ณ ์ถ์๋ฐ ์ฝ๋ฐฑ ์คํ ํ ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ 'Error message'๊ฐ ์ถ๋ ฅ๋์ง ์๊ณ ์ฝ์์ ์ถ๋ ฅ๋๋ ์ด์ ๋?๋น์ ์ ๊ทธ๊ฒ์ ํด๊ฒฐ ํ์ต๋๊น, ๊ฐ์ ์ํฉ์ด ๋ฐ์ํ์ต๋๋ค
์ ๋ ์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.์ด๊ธฐ๊ฐ์ด ๋น์ด์์ผ๋ฉด ์ ์ ์ ๋ ฅ ํ onblur ์๊ฐ์ ํตํด ์ปค์คํ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๊ฐ ์ ์์ ์ผ๋ก ์คํ๋ ์ ์์ผ๋ฉฐ ์ค๋ฅ๊ฐ ์์ผ๋ฉด ํ๋กฌํํธ๊ฐ ํ์๋์ง๋ง ์ด๊ธฐ ์ด๊ธฐ๊ฐ์ ๊ฐ์ด ์์ ๋ validatefields๋ ๋ชจ๋ ์์ ๊ตฌ์ฑ ์์์ ํตํฉ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํ๊ณ err์ null๋ก ์ถ๋ ฅ๋๋ฉฐ ์ ์ ํ ์ ํจ์ฑ ๊ฒ์ฌ ์คํจ๊ฐ ์ฝ์์ ๋ค์ ํ์ ๋ฉ๋๋ค. ์ฌ์ฉ์ ์ ์ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๋ ๋น๋๊ธฐ ์์ ์ ๋๋ค.
๋๋ ๋น์ ์ด ๋ฐํ์ ์ญ์ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค; ๊ธฐ๋ฅ์์ ๋ค์ ์๋ํ์ญ์์ค.์ ์ฉํ ์ ์์ต๋๋ค.
------------------ ์๋ณธ ๋ฉ์์ง ------------------
๋ณด๋ธ ์ฌ๋: "Ivan-hl"< [email protected]>;
๋ฐฐ์ก ์๊ฐ: 2019๋
11์ 20์ผ(์์์ผ) ์คํ 5์ 19๋ถ
๋ฐ๋ ์ฌ๋: "ant-design/ant-design"< [email protected]>;
์ฐธ์กฐ: "์ฃผ"< [email protected]>, "์๋"< [email protected]>;
์ ๋ชฉ: Re: [ant-design/ant-design] Form ์ปดํฌ๋ํธ์ validator ํจ์์ ํญ์ callback()
๊ฐ ํ์ํ ์ด์ ๋ ๋ฌด์์
๋๊น?ํผ ๊ท์น์์ validator๋ฅผ ์ฌ์ฉํ ๋ ๋ฉ์๋ ๋ณธ๋ฌธ์ด ํญ์ callback()์ ํธ์ถํด์ผ ํ๋ ์ด์ ๊ฒ์ฆ?(#5155)
๊ท์น์์ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ง์ ํ์ธ์ ์ํํ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
validateFunc = (๊ท์น, ๊ฐ, ์ฝ๋ฐฑ) => {
์ฌ์ค์ด๋ฉด) {
console.log(11);
callback('์ค๋ฅ ๋ฉ์์ง');
๋ฐํ;
}
์ฝ๋ฐฑ();
};
ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ ํ์ธ ๊ฒฐ๊ณผ 'Error message'๋ฅผ ํ์ํ๊ณ ์ถ์๋ฐ ์ฝ๋ฐฑ ์คํ ํ ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ 'Error message'๊ฐ ์ถ๋ ฅ๋์ง ์๊ณ ์ฝ์์ ์ถ๋ ฅ๋๋ ์ด์ ๋?
๊ท์น์์ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ง์ ํ์ธ์ ์ํํ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
validateFunc = (๊ท์น, ๊ฐ, ์ฝ๋ฐฑ) => {
์ฌ์ค์ด๋ฉด) {
console.log(11);
callback('์ค๋ฅ ๋ฉ์์ง');
๋ฐํ;
}
์ฝ๋ฐฑ();
};
ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ ํ์ธ ๊ฒฐ๊ณผ 'Error message'๋ฅผ ํ์ํ๊ณ ์ถ์๋ฐ ์ฝ๋ฐฑ ์คํ ํ ํด๋น FormItem ์ปดํฌ๋ํธ ์๋์ 'Error message'๊ฐ ์ถ๋ ฅ๋์ง ์๊ณ ์ฝ์์ ์ถ๋ ฅ๋๋ ์ด์ ๋?
๋น์ ์ ๊ทธ๊ฒ์ ํด๊ฒฐ ํ์ต๋๊น, ๊ฐ์ ์ํฉ์ด ๋ฐ์ํ์ต๋๋ค
์ ๋ ์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.์ด๊ธฐ๊ฐ์ด ๋น์ด์์ผ๋ฉด ์ ์ ์ ๋ ฅ ํ onblur ์๊ฐ์ ํตํด ์ปค์คํ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๊ฐ ์ ์์ ์ผ๋ก ์คํ๋ ์ ์์ผ๋ฉฐ ์ค๋ฅ๊ฐ ์์ผ๋ฉด ํ๋กฌํํธ๊ฐ ํ์๋์ง๋ง ์ด๊ธฐ ์ด๊ธฐ๊ฐ์ ๊ฐ์ด ์์ ๋ validatefields๋ ๋ชจ๋ ์์ ๊ตฌ์ฑ ์์์ ํตํฉ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํ๊ณ err์ null๋ก ์ถ๋ ฅ๋๋ฉฐ ์ ์ ํ ์ ํจ์ฑ ๊ฒ์ฌ ์คํจ๊ฐ ์ฝ์์ ๋ค์ ํ์ ๋ฉ๋๋ค. ์ฌ์ฉ์ ์ ์ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๋ ๋น๋๊ธฐ ์์ ์ ๋๋ค.
โ
์ด ์ค๋ ๋์ ๊ฐ์
ํ๊ธฐ ๋๋ฌธ์ ์ด ๋ฉ์์ง๋ฅผ ๋ฐ๊ณ ์์ต๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ฑฐ๋ GitHub์์ ๋ณด๊ฑฐ๋ ๊ตฌ๋
์ ์ทจ์ํ์ธ์.
๋๋ฌด ๋์จ
ํ์ธ ๊ธฐ๋ฅ์ ์์ธ๊ฐ ์์ผ๋ฉด ํ๋กฌํํธ๊ฐ ํ์๋์ง ์์ต๋๋ค.
์ค๋ซ๋์ ๊ตฌ๋ฉ์ด์ ๋น ์ก์ต๋๋ค. . .
์ด AntdV๊ฐ ์ ์ง๋์ง ์๋์ง ๊ถ๊ธํฉ๋๋ค.
@kongling94 ?
๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋๋ฐ ๋ ์ด์ ํ ์คํธ๊ฐ ์์ต๋๊น?
<a-input id="code" placeholder="่ฏท่พๅ
ฅ็จๆทID"v-decorator="[
'code',
{rules: [{ required: true, message: '่ฏท่พๅ
ฅ็จๆทID' }, { validator: handleUsername }], validateTrigger: 'change'}
]"
>
</a-input>
handleUsername(rule, value, callback) {
value = value.trim()
if (value.length == 0) {
this.username = '';
callback();
} else {
fetchUsername({
code: value
})
.then((rest) => {
if (rest.code == 200) {
this.username = rest.data;
//callback();
} else {
this.username = '';
callback(new Error(rest.msg))
return;
}
}).finally(() => {
callback()
})
}
},
<a-form :label-col="labelCol" :wrapper-col="wrapperCol" :form="form" @submit="handleSubmit">
<a-button type="primary" htmlType="submit">็กฎๅฎ</a-button>
</a-form>
์๋ต๊ณผ ํ๋กฌํํธ๊ฐ ์๋์ง ํ์ธํ๋ ค๋ฉด ํด๋ฆญํ๊ณ ์ฝ์์ async-validator:["code is required"]๋ฅผ ์
๋ ฅํฉ๋๋ค.
validateFields๋ฅผ ์ ํ ์
๋ ฅํ์ง ๋ง์ญ์์ค.
์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ์ validateTrigger๋ฅผ ์ ๊ฑฐํ๊ณ ํ์ธ์ ํด๋ฆญํ๋ฉด ์ ์์ ์ผ๋ก ํ๋กฌํํธ๊ฐ ํ์๋ฉ๋๋ค.
๋ฌธ์ ๊ฐ ๋ฌด์์
๋๊น?
<a-input id="code" placeholder="่ฏท่พๅ ฅ็จๆทID"v-decorator="[ 'code', {rules: [{ required: true, message: '่ฏท่พๅ ฅ็จๆทID' }, { validator: handleUsername }], validateTrigger: 'change'} ]" > </a-input>
handleUsername(rule, value, callback) { value = value.trim() if (value.length == 0) { this.username = ''; callback(); } else { fetchUsername({ code: value }) .then((rest) => { if (rest.code == 200) { this.username = rest.data; //callback(); } else { this.username = ''; callback(new Error(rest.msg)) return; } }).finally(() => { callback() }) } },
<a-form :label-col="labelCol" :wrapper-col="wrapperCol" :form="form" @submit="handleSubmit"> <a-button type="primary" htmlType="submit">็กฎๅฎ</a-button> </a-form>
์๋ต๊ณผ ํ๋กฌํํธ๊ฐ ์๋์ง ํ์ธํ๋ ค๋ฉด ํด๋ฆญํ๊ณ ์ฝ์์ async-validator:["code is required"]๋ฅผ ์ ๋ ฅํฉ๋๋ค.
validateFields๋ฅผ ์ ํ ์ ๋ ฅํ์ง ๋ง์ญ์์ค.
์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ์ validateTrigger๋ฅผ ์ ๊ฑฐํ๊ณ ํ์ธ์ ํด๋ฆญํ๋ฉด ์ ์์ ์ผ๋ก ํ๋กฌํํธ๊ฐ ํ์๋ฉ๋๋ค.
๋ฌธ์ ๊ฐ ๋ฌด์์ ๋๊น?
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ จ์ต๋๊น?๋ํ์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
<a-input id="code" placeholder="่ฏท่พๅ ฅ็จๆทID"v-decorator="[ 'code', {rules: [{ required: true, message: '่ฏท่พๅ ฅ็จๆทID' }, { validator: handleUsername }], validateTrigger: 'change'} ]" > </a-input>
handleUsername(rule, value, callback) { value = value.trim() if (value.length == 0) { this.username = ''; callback(); } else { fetchUsername({ code: value }) .then((rest) => { if (rest.code == 200) { this.username = rest.data; //callback(); } else { this.username = ''; callback(new Error(rest.msg)) return; } }).finally(() => { callback() }) } },
<a-form :label-col="labelCol" :wrapper-col="wrapperCol" :form="form" @submit="handleSubmit"> <a-button type="primary" htmlType="submit">็กฎๅฎ</a-button> </a-form>
์๋ต๊ณผ ํ๋กฌํํธ๊ฐ ์๋์ง ํ์ธํ๋ ค๋ฉด ํด๋ฆญํ๊ณ ์ฝ์์ async-validator:["code is required"]๋ฅผ ์ ๋ ฅํฉ๋๋ค.
validateFields๋ฅผ ์ ํ ์ ๋ ฅํ์ง ๋ง์ญ์์ค.
์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ์ validateTrigger๋ฅผ ์ ๊ฑฐํ๊ณ ํ์ธ์ ํด๋ฆญํ๋ฉด ์ ์์ ์ผ๋ก ํ๋กฌํํธ๊ฐ ํ์๋ฉ๋๋ค.
๋ฌธ์ ๊ฐ ๋ฌด์์ ๋๊น?์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ จ์ต๋๊น?๋ํ์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
// ่ชๅฎไนๅฏ็ ๆ ก้ช
handleConfirmPassword = (rule, value, callback) => {
const { getFieldValue } = this.props.form;
if (value && value !== getFieldValue('newPwd')) {
callback('ไธคๆฌก่พๅ
ฅไธไธ่ด๏ผ');
}
// Note: ๅฟ
้กปๆปๆฏ่ฟๅไธไธช callback๏ผๅฆๅ validateFieldsAndScroll ๆ ๆณๅๅบ
callback();
};
ๆๆฏ่ฟไน่งฃๅณ็
validatorFun(๊ท์น, ๊ฐ, ์ฝ๋ฐฑ) {
const psw = this.form.getFieldValue('newPwd')
if (๊ฐ && ๊ฐ !== psw) {
rule.message = 'ไธคๆฌกๅฏ็ ไธไธ่ด'
์ฝ๋ฐฑ(๊ท์น)
}
์ฝ๋ฐฑ()
}
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋๋ ๋ถํํ๋ค https://www.zhihu.com/question/33629737/answer/150154145
์ฐ๋ฆฌ์ ์คํ ์์ค ์์น ์ค ํ๋๊ฐ ๋ฌผ๊ณผ ํ์ ๋ฎ๋ ๊ฒ์ด๋ผ๋ ๋ฌธ์๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.