Ant-design: mengapa kita selalu membutuhkan `callback()` dalam fungsi validator pada komponen Form?

Dibuat pada 3 Mar 2017  ·  38Komentar  ·  Sumber: ant-design/ant-design

Terima kasih telah menyediakan serangkaian komponen seperti Formulir.

Deskripsi Masalah

Karena setiap bidang dalam formulir perlu diverifikasi lagi sebelum dikirim, validateFieldsAndScroll . Namun penemuan itu tidak berpengaruh.

Setelah debugging, ditemukan bahwa jika satu set bidang tertentu diteruskan ke fungsi, itu bisa berlaku. Tetapi selama kumpulan file ini berisi salah satu yang menentukan penggunaan validator dalam aturan verifikasi untuk verifikasi tambahan, seluruh metode validateFields tidak akan berlaku.

Pada akhirnya, saya menemukan bahwa itu karena saya tidak selalu mengembalikan callback() di validator callback yang sesuai di awal (saya pikir ini lebih dari itu, dan Anda dapat melakukannya itu untuk satu input tanpa menulis di awal. Cek normal). Setelah ditambahkan, tidak apa-apa.

Bingung

Permisi, apakah ini bug? Karena tidak ditunjukkan dalam dokumen, validator harus dikembalikan dalam callback() .
Jika perlu untuk mengembalikan callback , disarankan untuk mengingatkan pengembang dalam dokumen, atau dapat default secara default.

segmen kode

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>

Lingkungan

  • versi antd: terbaru
  • OS dan versinya: OS X
  • Browser dan versinya: chrome terbaru
Usage ❓FAQ 🙅🏻‍♀️ WON'T RESOLVE

Komentar yang paling membantu

Saya mengeluh https://www.zhihu.com/question/33629737/answer/150154145

Anda dapat menambahkan dokumen yang menyatakan bahwa salah satu prinsip open source kami adalah menutupi air dan bumi.

Semua 38 komentar

Ini dirancang: https://github.com/yiminghe/async-validator/

BTW, bagaimana async-validator mengetahui prosedur asinkron telah berakhir, jika Anda tidak menggunakan callback untuk memberi tahu?

Saya mengeluh https://www.zhihu.com/question/33629737/answer/150154145

Anda dapat menambahkan dokumen yang menyatakan bahwa salah satu prinsip open source kami adalah menutupi air dan bumi.

Dokumen telah diperbarui.

Halo, bisakah penggunaan ini hanya ditulis di kelas?
Apakah mungkin untuk menulis React Component dengan cara yang murni fungsional.Jika demikian, apakah ada kasus?

Desain API ini benar-benar tidak elegan. Saya merasa hanya ingin memeriksa apakah kotak centang tertentu dipilih:

rules: [
            {
              message: 'You need to agree to our terms to sign up.',
              validator: (rule, value, cb) => (value === true ? cb() : cb(true)),
            },
          ],

Dan parameter pertama yang diberikan ke panggilan balik adalah pesan kesalahan, yang juga berlebihan dengan message (walaupun tampaknya selama apa pun dikembalikan, message akan digunakan, itu harus ditutupi oleh message Pesan kesalahan).

Penggunaan yang diharapkan dari sebagian besar pengguna harus langsung mengembalikan true atau false untuk menentukan benar atau salah:

rules: [
            {
              message: 'You need to agree to our terms to sign up.',
              validator: (rule, value, cb) => value === true,
            },
          ],

Tersedia, tetapi masih disarankan untuk mengoptimalkan API ini, yaitu menggunakan https://github.com/yiminghe/async-validator/ , tetapi ANT dapat diselesaikan di sini dan dapat dienkapsulasi saat panggilan

@neekey dapat pergi dan mengirimkan PR yang kompatibel ke async-validator

@neekey antarmuka aneh ini adalah untuk mencapai:

  • Validasi asinkron
  • Mendukung kesalahan yang berbeda dan mengembalikan pesan yang berbeda

Apakah ada cara yang lebih baik?

<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

Setiap kali saya menemukan verifikasi fungsi, saya akan datang ke sini untuk melihatnya sekali. Sangat sulit untuk diingat

fungsi validator

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);
  }

Bukankah itu kesalahan panggilan balik terpadu? Rasanya cukup masuk akal.
Saya tidak tahu apakah antd versi baru sudah mulai membedakan antara verifikasi asinkron dan sinkron? validator (sinkron) asyncValidator (asinkron)

Bagaimana cara memanggil prompt pesan ini dalam panggilan balik yang dikembalikan oleh latar belakang setelah permintaan

Saya mengalami masalah saat menggunakan validator dalam aturan untuk melakukan verifikasi khusus
validasiFunc = (aturan, nilai, panggilan balik) => {
jika benar) {
console.log(11);
panggilan balik('Pesan eror');
kembali;
}
panggilan balik();
};
Saya ingin 'Pesan kesalahan' hasil verifikasi ditampilkan di bawah komponen FormItem yang sesuai, tetapi setelah panggilan balik dijalankan, 'Pesan kesalahan' tidak ditampilkan di bawah komponen FormItem yang sesuai, tetapi dicetak di konsol. Mengapa?

Bagaimana Anda menulis logika 在对应的FormItem组件下显示 ?

@neekey dapat pergi dan mengirimkan PR yang kompatibel ke async-validator

Seseorang menyebutkannya, kata yiminghe, menentang.

Bagaimana Anda menulis logika 在对应的FormItem组件下显示 ?

Saya mengubah skema verifikasi khusus, dan dinilai di onFieldsChange(), jika aturan khusus tidak terpenuhi, maka kesalahan akan langsung diubah, dan kemudian informasi kesalahan akan ditampilkan di kontrol.
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, }, }); }

Mengapa prompt berikut tidak hilang setelah verifikasi berlalu?

Ajukan pertanyaan, bisakah validator ini tidak melakukan verifikasi saat halaman dimuat?

@neekey
harus memanggil fitur

<Form>
          <Form.Item ...>
            {getFieldDecorator('name', {validator: (rule, value, callback) => setTimeout(callback(), 1000)})(
                <Input placeholder="name" />
            )}
          </Form.Item>
....

dan sebelum setTimeout diaktifkan, seluruh komponen dilepas. Kemudian batas waktu diaktifkan, panggilan baliknya diaktifkan dan

komponen akan menggunakan setState (saya kira) yang akan menghasilkan kesalahan berikut:

Peringatan: Tidak dapat melakukan pembaruan status Bereaksi pada komponen yang tidak dipasang. Ini adalah larangan, tetapi ini menunjukkan kebocoran memori di aplikasi Anda. Untuk memperbaikinya, batalkan semua langganan dan tugas asinkron dalam metode componentWillUnmount.

Sayangnya panggilan balik tidak dapat dibatalkan! Tidak ada cara untuk menghindari kesalahan ini!

@jiufengdadi
Saya mengalami masalah ini.
Solusi saya adalah meneruskan undefined ke dalam callback . Validator akan lulus ketika parameter pertama dari callback adalah array kosong. Dan itu menetapkan nilai default ke parameter, jadi undefined juga berfungsi.

definisi callback : L146

Mengapa async-validator: [""] muncul setelah validasi khusus saya disahkan,

Jika ada dua pemeriksaan, yang pertama akan gagal, mengapa?
```
aturan: [
{
diperlukan: benar,
pesan: 'Masukkan nomor telepon Anda',
},
{
validator: (aturan, nilai, panggilan balik) => {
mencoba {
if (this.props.form.getFieldValue('prefix') == 86 && nilai) {
const reg = /^1d{10}$/;
if (!reg.test(nilai)) {
throw new Error('Ada yang salah!');
}
}
} tangkap (keliru) {
panggilan balik(err);
}
},
pesan:'Silakan masukkan nomor ponsel yang valid',
},
],

 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: '请输入有效手机号',
                },
              ],

Saya mengalami masalah saat menggunakan validator dalam aturan untuk melakukan verifikasi khusus
validasiFunc = (aturan, nilai, panggilan balik) => {
jika benar) {
console.log(11);
panggilan balik('Pesan eror');
kembali;
}
panggilan balik();
};
Saya ingin 'Pesan kesalahan' hasil verifikasi ditampilkan di bawah komponen FormItem yang sesuai, tetapi setelah panggilan balik dijalankan, 'Pesan kesalahan' tidak ditampilkan di bawah komponen FormItem yang sesuai, tetapi dicetak di konsol. Mengapa?

Saya mengalami masalah saat menggunakan validator dalam aturan untuk melakukan verifikasi khusus
validasiFunc = (aturan, nilai, panggilan balik) => {
jika benar) {
console.log(11);
panggilan balik('Pesan eror');
kembali;
}
panggilan balik();
};
Saya ingin 'Pesan kesalahan' hasil verifikasi ditampilkan di bawah komponen FormItem yang sesuai, tetapi setelah panggilan balik dijalankan, 'Pesan kesalahan' tidak ditampilkan di bawah komponen FormItem yang sesuai, tetapi dicetak di konsol. Mengapa?

Apakah Anda menyelesaikannya, mengalami situasi yang sama

 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: '请输入有效手机号',
                },
              ],

Apakah prompt pesan akan diulang? 'Silakan masukkan nomor ponsel, masukkan nomor ponsel yang valid' mirip dengan ini

 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: '请输入有效手机号',
                },
              ],

Apakah prompt pesan akan diulang? 'Silakan masukkan nomor ponsel, masukkan nomor ponsel yang valid' mirip dengan ini

Tidak akan

image

Lakukan sebagai berikut
image

Mengapa centang merah tidak hilang? ? ? Bagaimana cara melakukan verifikasi pengaruh timbal balik semacam ini yang memenuhi spesifikasi? ? ?

Callback validator aturan harus dipanggil apakah berhasil atau gagal, perbedaannya adalah parameternya tidak diteruskan.

Saya mengalami masalah saat menggunakan validator dalam aturan untuk melakukan verifikasi khusus
validasiFunc = (aturan, nilai, panggilan balik) => {
jika benar) {
console.log(11);
panggilan balik('Pesan eror');
kembali;
}
panggilan balik();
};
Saya ingin 'Pesan kesalahan' hasil verifikasi ditampilkan di bawah komponen FormItem yang sesuai, tetapi setelah panggilan balik dijalankan, 'Pesan kesalahan' tidak ditampilkan di bawah komponen FormItem yang sesuai, tetapi dicetak di konsol. Mengapa?

Saya mengalami masalah saat menggunakan validator dalam aturan untuk melakukan verifikasi khusus
validasiFunc = (aturan, nilai, panggilan balik) => {
jika benar) {
console.log(11);
panggilan balik('Pesan eror');
kembali;
}
panggilan balik();
};
Saya ingin 'Pesan kesalahan' hasil verifikasi ditampilkan di bawah komponen FormItem yang sesuai, tetapi setelah panggilan balik dijalankan, 'Pesan kesalahan' tidak ditampilkan di bawah komponen FormItem yang sesuai, tetapi dicetak di konsol. Mengapa?

Apakah Anda menyelesaikannya, mengalami situasi yang sama

Saya juga mengalami masalah ini.Jika nilai awal kosong, validator khusus dapat dipicu secara normal melalui waktu onblur setelah input normal dan prompt akan diberikan jika ada kesalahan, tetapi setelah nilai awal awal memiliki nilai, Kapan validasifields melakukan validasi terpadu untuk semua komponen formulir, err dicetak sebagai null, dan setelah beberapa saat, kegagalan validasi akan muncul lagi di konsol. Validator kustom adalah tindakan asinkron

Saya pikir Anda menghapus pengembalian; dalam fungsi dan coba lagi. Mungkin berguna.

------------------ Pesan aslinya ------------------
Dari: "Ivan-hl"< [email protected]>;
Waktu pengiriman: 20 November 2019 (Rabu) 17:19
Penerima: "desain semut/desain semut"< [email protected]>;
Cc: "wk"< [email protected]>; "Manual"< [email protected]>;
Perihal: Re: [ant-design/ant-design] mengapa kita selalu membutuhkan callback() dalam fungsi validator pada komponen Form? Mengapa badan metode selalu perlu memanggil callback() saat menggunakan validator dalam aturan form validasi? (#5155)

Saya mengalami masalah saat menggunakan validator dalam aturan untuk melakukan verifikasi khusus
validasiFunc = (aturan, nilai, panggilan balik) => {
jika benar) {
console.log(11);
panggilan balik('Pesan eror');
kembali;
}
panggilan balik();
};
Saya ingin 'Pesan kesalahan' hasil verifikasi ditampilkan di bawah komponen FormItem yang sesuai, tetapi setelah panggilan balik dijalankan, 'Pesan kesalahan' tidak ditampilkan di bawah komponen FormItem yang sesuai, tetapi dicetak di konsol. Mengapa?

Saya mengalami masalah saat menggunakan validator dalam aturan untuk melakukan verifikasi khusus
validasiFunc = (aturan, nilai, panggilan balik) => {
jika benar) {
console.log(11);
panggilan balik('Pesan eror');
kembali;
}
panggilan balik();
};
Saya ingin 'Pesan kesalahan' hasil verifikasi ditampilkan di bawah komponen FormItem yang sesuai, tetapi setelah panggilan balik dijalankan, 'Pesan kesalahan' tidak ditampilkan di bawah komponen FormItem yang sesuai, tetapi dicetak di konsol. Mengapa?

Apakah Anda menyelesaikannya, mengalami situasi yang sama

Saya juga mengalami masalah ini.Jika nilai awal kosong, validator khusus dapat dipicu secara normal melalui waktu onblur setelah input normal dan prompt akan diberikan jika ada kesalahan, tetapi setelah nilai awal awal memiliki nilai, Kapan validasifields melakukan validasi terpadu untuk semua komponen formulir, err dicetak sebagai null, dan setelah beberapa saat, kegagalan validasi akan muncul lagi di konsol. Validator kustom adalah tindakan asinkron


Anda menerima ini karena Anda berlangganan utas ini.
Balas email ini secara langsung, lihat di GitHub, atau berhenti berlangganan.

Sangat buruk

Jika ada pengecualian dalam fungsi cek, tidak ada prompt.
Diadu dalam waktu yang lama. . .

Saya ingin tahu apakah AntdV ini tidak dipertahankan

@kongling94 ?

Mengalami masalah yang sama, tidak ada lagi teks?

<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>
Klik untuk mengonfirmasi bahwa tidak ada respons dan tidak ada prompt, masukkan async-validator:["code is required"] di konsol
Tidak masuk validasiFields sama sekali
Hapus validator dan validationTrigger dan klik OK dan itu akan meminta secara normal.
Apa masalahnya?

<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>
Klik untuk mengonfirmasi bahwa tidak ada respons dan tidak ada prompt, masukkan async-validator:["code is required"] di konsol
Tidak masuk validasiFields sama sekali
Hapus validator dan validationTrigger dan klik OK dan itu akan meminta secara normal.
Apa masalahnya?

Apakah Anda memecahkan masalah ini?Juga mengalami masalah ini

<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>
Klik untuk mengonfirmasi bahwa tidak ada respons dan tidak ada prompt, masukkan async-validator:["code is required"] di konsol
Tidak masuk validasiFields sama sekali
Hapus validator dan validationTrigger dan klik OK dan itu akan meminta secara normal.
Apa masalahnya?

Apakah Anda memecahkan masalah ini?Juga mengalami masalah ini

// 自定义密码校验
  handleConfirmPassword = (rule, value, callback) => {
    const { getFieldValue } = this.props.form;
    if (value && value !== getFieldValue('newPwd')) {
      callback('两次输入不一致!');
    }

    // Note: 必须总是返回一个 callback,否则 validateFieldsAndScroll 无法响应
    callback();
  };
我是这么解决的

validatorFun(aturan, nilai, panggilan balik) {
const psw = this.form.getFieldValue('newPwd')
if (nilai && nilai !== psw) {
aturan.pesan = '两次密码不一致'
panggilan balik (aturan)
}
panggilan balik()
}

Apakah halaman ini membantu?
0 / 5 - 0 peringkat