Ant-design: Warum brauchen wir immer `callback()` in der Validator-Funktion der Form-Komponente?

Erstellt am 3. März 2017  ·  38Kommentare  ·  Quelle: ant-design/ant-design

Vielen Dank für die Bereitstellung einer Reihe von Komponenten wie Form.

Problembeschreibung

Da jedes Feld im Formular vor dem Absenden erneut überprüft werden muss, wird validateFieldsAndScroll . Aber die Entdeckung zeigte keine Wirkung.

Nach dem Debuggen wurde festgestellt, dass die Funktion wirksam werden kann, wenn eine Reihe von angegebenen Feldern an die Funktion übergeben wird. Aber solange dieser Satz von Feldern eines enthält, das die Verwendung von validator in den Verifizierungsregeln für die Hilfsverifizierung angibt, wird die gesamte Methode validateFields nicht wirksam.

Am Ende fand ich heraus, dass es daran lag, dass ich am Anfang nicht immer callback() im entsprechenden validator Callback zurückgegeben habe (ich denke, es ist viel mehr als das, und das kannst du tun es für eine einzelne Eingabe ohne Schreiben am Anfang (Normale Prüfung). Nach dem Hinzufügen ist es in Ordnung.

Verwechseln

Entschuldigung, ist das ein Bug? Da im Dokument nicht darauf hingewiesen wird, muss validator in callback() .
Wenn callback , wird empfohlen, den Entwickler im Dokument daran zu erinnern, oder es kann standardmäßig voreingestellt werden.

Codesegment

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>

Umfeld

  • antd-Version: neueste
  • Betriebssystem und seine Version: OS X
  • Browser und seine Version: Chrome neueste
Usage ❓FAQ 🙅🏻‍♀️ WON'T RESOLVE

Hilfreichster Kommentar

Ich wurde beschwert https://www.zhihu.com/question/33629737/answer/150154145

Sie können ein Dokument hinzufügen, das besagt, dass eines unserer Open-Source-Prinzipien darin besteht, Wasser und Erde zu vertuschen.

Alle 38 Kommentare

Es ist so konzipiert: https://github.com/yiminghe/async-validator/

Übrigens, woher weiß der async-validator, dass eine asynchrone Prozedur beendet ist, wenn Sie callback , um dies zu benachrichtigen?

Ich wurde beschwert https://www.zhihu.com/question/33629737/answer/150154145

Sie können ein Dokument hinzufügen, das besagt, dass eines unserer Open-Source-Prinzipien darin besteht, Wasser und Erde zu vertuschen.

Das Dokument wurde aktualisiert.

Hallo, kann diese Verwendung nur im Unterricht geschrieben werden?
Ist es möglich, React Component rein funktional zu schreiben, wenn ja, gibt es Fälle?

Dieses API-Design ist wirklich unelegant, ich habe das Gefühl, dass ich nur überprüfen möchte, ob ein bestimmtes Kontrollkästchen aktiviert ist:

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

Und der erste Parameter, der dem Callback übergeben wird, ist die Fehlermeldung, die auch mit message überflüssig ist (obwohl es scheint, dass message wird, solange etwas zurückgegeben wird, sollte es abgedeckt werden durch message Fehlermeldung).

Die erwartete Verwendung der meisten Benutzer sollte darin bestehen, true oder false direkt zurückzugeben, um richtig oder falsch zu bestimmen:

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

Verfügbar, aber es wird immer noch empfohlen, diese API zu optimieren, d. h. https://github.com/yiminghe/async-validator/ zu verwenden, aber ANT kann hier abgeschlossen und beim Aufruf gekapselt werden

@neekey kann gehen und eine kompatible PR an async-

@neekey diese seltsame Schnittstelle soll erreicht werden:

  • Asynchrone Validierung
  • Unterstützen Sie verschiedene Fehler und geben Sie verschiedene Nachrichten zurück

Gibt es einen besseren Weg?

<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

Jedes Mal, wenn ich auf eine Funktionsüberprüfung stoße, komme ich hierher, um sie einmal zu sehen. Es ist wirklich schwer, sich daran zu erinnern

Validierungsfunktion

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

Ist es nicht ein einheitlicher Rückruffehler?Es fühlt sich ganz vernünftig an.
Ich weiß nicht, ob die neue Version von antd begonnen hat, zwischen asynchroner und synchroner Verifizierung zu unterscheiden?validator (synchron) asyncValidator (asynchron)

So rufen Sie diese Meldungsaufforderung im Rückruf auf, der vom Hintergrund nach der Anfrage zurückgegeben wird

Ich bin auf ein Problem gestoßen, als ich den Validator in der Regel verwendet habe, um eine benutzerdefinierte Überprüfung durchzuführen
ValidateFunc = (Regel, Wert, Rückruf) => {
Wenn wahr) {
Konsole.log(11);
Rückruf('Fehlermeldung');
Rückkehr;
}
Ruf zurück();
};
Ich möchte, dass das Überprüfungsergebnis 'Fehlermeldung' unter der entsprechenden FormItem-Komponente angezeigt wird, aber nach der Ausführung des Rückrufs wird die 'Fehlermeldung' nicht unter der entsprechenden FormItem-Komponente angezeigt, sondern auf der Konsole ausgedruckt.

Wie schreiben Sie die Logik Ihres 在对应的FormItem组件下显示 ?

@neekey kann gehen und eine kompatible PR an async-

Jemand hat es erwähnt, sagte Yiminghe, widersetzte sich.

Wie schreiben Sie die Logik Ihres 在对应的FormItem组件下显示 ?

Ich habe das benutzerdefinierte Überprüfungsschema geändert und in onFieldsChange() beurteilt, wenn die benutzerdefinierten Regeln nicht eingehalten werden, werden die Fehler direkt geändert und dann werden die Fehlerinformationen im Steuerelement angezeigt.
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, }, }); }

Warum verschwindet die folgende Eingabeaufforderung nicht, nachdem die Überprüfung bestanden wurde?

Stellen Sie eine Frage, kann dieser Validator keine Überprüfung durchführen, wenn die Seite geladen wird?

@neekey
muss eine Rückruffunktion aufrufen, ist ein großer Nachteil in einer asynchronen Situation:

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

und bevor setTimeout ausgelöst wird, wird die gesamte Komponente ausgehängt. Dann wird der Timeout ausgelöst, sein Callback wird ausgelöst und

Komponente verwendet setState (vermutlich), was zu folgendem Fehler führt:

Warnung: Es kann kein React-Status-Update für eine nicht gemountete Komponente durchgeführt werden. Dies ist ein No-Op, weist jedoch auf ein Speicherleck in Ihrer Anwendung hin. Um das Problem zu beheben, brechen Sie alle Abonnements und asynchronen Aufgaben in der Methode componentWillUnmount ab.

Der Rückruf ist leider nicht stornierbar! Dieser Fehler kann nicht vermieden werden!

@jiufengdadi
Ich bin auf dieses Problem gestoßen.
Meine Lösung ist undefined in callback . Der Validator wird bestehen, wenn der erste Parameter von callback ein leeres Array ist. Und es setzt einen Standardwert für den Parameter, sodass undefined auch funktioniert.

die callback Definition: L146

Warum wird async-validator: [""] angezeigt, nachdem meine benutzerdefinierte Validierung bestanden wurde,

Wenn es zwei Prüfungen gibt, schlägt die erste fehl.
```
Regeln: [
{
erforderlich: wahr,-
Nachricht:'Bitte geben Sie Ihre Telefonnummer ein',
},
{
validator: (Regel, Wert, Rückruf) => {
Versuchen {
if (this.props.form.getFieldValue('prefix') == 86 && Wert) {
const reg = /^1d{10}$/;
if (!reg.test(wert)) {
throw new Error('Etwas stimmt nicht!');
}
}
} fangen (irren) {
Rückruf (Fehler);
}
},
Nachricht:'Bitte geben Sie eine gültige Handynummer ein',
},
],

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

Ich bin auf ein Problem gestoßen, als ich den Validator in der Regel verwendet habe, um eine benutzerdefinierte Überprüfung durchzuführen
ValidateFunc = (Regel, Wert, Rückruf) => {
Wenn wahr) {
Konsole.log(11);
Rückruf('Fehlermeldung');
Rückkehr;
}
Ruf zurück();
};
Ich möchte, dass das Überprüfungsergebnis 'Fehlermeldung' unter der entsprechenden FormItem-Komponente angezeigt wird, aber nach der Ausführung des Rückrufs wird die 'Fehlermeldung' nicht unter der entsprechenden FormItem-Komponente angezeigt, sondern auf der Konsole ausgedruckt.

Ich bin auf ein Problem gestoßen, als ich den Validator in der Regel verwendet habe, um eine benutzerdefinierte Überprüfung durchzuführen
ValidateFunc = (Regel, Wert, Rückruf) => {
Wenn wahr) {
Konsole.log(11);
Rückruf('Fehlermeldung');
Rückkehr;
}
Ruf zurück();
};
Ich möchte, dass das Überprüfungsergebnis 'Fehlermeldung' unter der entsprechenden FormItem-Komponente angezeigt wird, aber nach der Ausführung des Rückrufs wird die 'Fehlermeldung' nicht unter der entsprechenden FormItem-Komponente angezeigt, sondern auf der Konsole ausgedruckt.

Hast du es gelöst, bin auf die gleiche Situation gestoßen

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

Wird die Meldungsaufforderung wiederholt? 'Bitte geben Sie eine Handynummer ein, bitte geben Sie eine gültige Handynummer ein' ähnlich wie hier

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

Wird die Meldungsaufforderung wiederholt? 'Bitte geben Sie eine Handynummer ein, bitte geben Sie eine gültige Handynummer ein' ähnlich wie hier

Wird nicht

image

Gehen Sie wie folgt vor
image

Warum ist das rote Häkchen nicht verschwunden? ? ? Wie kann eine solche Überprüfung der gegenseitigen Beeinflussung durchgeführt werden, die den Spezifikationen entspricht? ? ?

Der Callback des Validators der Regel muss unabhängig davon aufgerufen werden, ob er erfolgreich ist oder fehlschlägt, mit dem Unterschied, dass die Parameter nicht übergeben werden.

Ich bin auf ein Problem gestoßen, als ich den Validator in der Regel verwendet habe, um eine benutzerdefinierte Überprüfung durchzuführen
ValidateFunc = (Regel, Wert, Rückruf) => {
Wenn wahr) {
Konsole.log(11);
Rückruf('Fehlermeldung');
Rückkehr;
}
Ruf zurück();
};
Ich möchte, dass das Überprüfungsergebnis 'Fehlermeldung' unter der entsprechenden FormItem-Komponente angezeigt wird, aber nach der Ausführung des Rückrufs wird die 'Fehlermeldung' nicht unter der entsprechenden FormItem-Komponente angezeigt, sondern auf der Konsole ausgedruckt.

Ich bin auf ein Problem gestoßen, als ich den Validator in der Regel verwendet habe, um eine benutzerdefinierte Überprüfung durchzuführen
ValidateFunc = (Regel, Wert, Rückruf) => {
Wenn wahr) {
Konsole.log(11);
Rückruf('Fehlermeldung');
Rückkehr;
}
Ruf zurück();
};
Ich möchte, dass das Überprüfungsergebnis 'Fehlermeldung' unter der entsprechenden FormItem-Komponente angezeigt wird, aber nach der Ausführung des Rückrufs wird die 'Fehlermeldung' nicht unter der entsprechenden FormItem-Komponente angezeigt, sondern auf der Konsole ausgedruckt.

Hast du es gelöst, bin auf die gleiche Situation gestoßen

Ich bin auch auf dieses Problem gestoßen.Wenn der Anfangswert leer ist, kann der benutzerdefinierte Validator normal durch die Onblur-Zeit nach der normalen Eingabe ausgelöst werden und eine Eingabeaufforderung wird gegeben, wenn ein Fehler auftritt, aber sobald der anfängliche Anfangswert einen Wert hat, Wenn Validatefields führt eine einheitliche Validierung aller Formularkomponenten durch, err wird als null ausgegeben und nach einer Weile wird der Validierungsfehler erneut in der Konsole angezeigt.Der benutzerdefinierte Validator ist eine asynchrone Aktion

Ich denke, Sie löschen die Rückgabe in der Funktion und versuchen es erneut. Es könnte nützlich sein.

------------------ Die ursprüngliche Nachricht ------------------
Von: "Ivan-hl"< [email protected]>;
Lieferzeit: 20.11.2019 (Mittwoch) 17:19
Empfänger: "ant-design/ant-design"< [email protected]>;
Cc: "wk"< [email protected]>; "Manual"< [email protected]>;
Betreff: Re: [ant-design/ant-design] Warum brauchen wir immer callback() in der Validator-Funktion der Form-Komponente?Warum muss der Methodenrumpf immer callback() aufrufen, wenn Validator in den Formularregeln verwendet wird? Validierung? (#5155)

Ich bin auf ein Problem gestoßen, als ich den Validator in der Regel verwendet habe, um eine benutzerdefinierte Überprüfung durchzuführen
ValidateFunc = (Regel, Wert, Rückruf) => {
Wenn wahr) {
Konsole.log(11);
Rückruf('Fehlermeldung');
Rückkehr;
}
Ruf zurück();
};
Ich möchte, dass das Überprüfungsergebnis 'Fehlermeldung' unter der entsprechenden FormItem-Komponente angezeigt wird, aber nach der Ausführung des Rückrufs wird die 'Fehlermeldung' nicht unter der entsprechenden FormItem-Komponente angezeigt, sondern auf der Konsole ausgedruckt.

Ich bin auf ein Problem gestoßen, als ich den Validator in der Regel verwendet habe, um eine benutzerdefinierte Überprüfung durchzuführen
ValidateFunc = (Regel, Wert, Rückruf) => {
Wenn wahr) {
Konsole.log(11);
Rückruf('Fehlermeldung');
Rückkehr;
}
Ruf zurück();
};
Ich möchte, dass das Überprüfungsergebnis 'Fehlermeldung' unter der entsprechenden FormItem-Komponente angezeigt wird, aber nach der Ausführung des Rückrufs wird die 'Fehlermeldung' nicht unter der entsprechenden FormItem-Komponente angezeigt, sondern auf der Konsole ausgedruckt.

Hast du es gelöst, bin auf die gleiche Situation gestoßen

Ich bin auch auf dieses Problem gestoßen.Wenn der Anfangswert leer ist, kann der benutzerdefinierte Validator normal durch die Onblur-Zeit nach der normalen Eingabe ausgelöst werden und eine Eingabeaufforderung wird gegeben, wenn ein Fehler auftritt, aber sobald der anfängliche Anfangswert einen Wert hat, Wenn Validatefields führt eine einheitliche Validierung aller Formularkomponenten durch, err wird als null ausgegeben und nach einer Weile wird der Validierungsfehler erneut in der Konsole angezeigt.Der benutzerdefinierte Validator ist eine asynchrone Aktion


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder melden Sie sich ab.

Schade

Bei einer Ausnahme in der Prüffunktion erfolgt keine Abfrage.
Lange Zeit geplättet. . .

Ich frage mich, ob diese AntdV nicht gepflegt wird

@kongling94 ?

Ist das gleiche Problem aufgetreten, kein Text mehr?

<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>
Klicken Sie, um zu bestätigen, dass keine Antwort und keine Eingabeaufforderung erfolgt, geben Sie async-validator:["code is required"] in die Konsole ein
Geben Sie validFields überhaupt nicht ein
Entfernen Sie Validator und ValidateTrigger und klicken Sie auf OK und es wird normal aufgefordert.
Was ist das Problem?

<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>
Klicken Sie, um zu bestätigen, dass keine Antwort und keine Eingabeaufforderung erfolgt, geben Sie async-validator:["code is required"] in die Konsole ein
Geben Sie validFields überhaupt nicht ein
Entfernen Sie Validator und ValidateTrigger und klicken Sie auf OK und es wird normal aufgefordert.
Was ist das Problem?

Haben Sie dieses Problem gelöst?Dieses Problem ist auch aufgetreten

<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>
Klicken Sie, um zu bestätigen, dass keine Antwort und keine Eingabeaufforderung erfolgt, geben Sie async-validator:["code is required"] in die Konsole ein
Geben Sie validFields überhaupt nicht ein
Entfernen Sie Validator und ValidateTrigger und klicken Sie auf OK und es wird normal aufgefordert.
Was ist das Problem?

Haben Sie dieses Problem gelöst?Dieses Problem ist auch aufgetreten

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

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

validatorFun(Regel, Wert, Rückruf) {
const psw = this.form.getFieldValue('newPwd')
if (Wert && Wert !== psw) {
rule.message = '两次密码不一致'
Rückruf (Regel)
}
Ruf zurück()
}

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen