Winkel: Implementieren der bedingten benutzerdefinierten Überprüfung

Angenommen, wir haben ein Formular, in das einige persönliche Familiendetails eingegeben werden können: Name, Geburtsdatum, Partnerdetails und Kinderdetails.

so was:

Und wir möchten, dass der Name des Kindes erforderlich ist, aber nur, wenn der Benutzer Kinder hat, wenn er keine Kinder hat, sollte er das Kontrollkästchen aktivieren: Ich habe keine Kinder

Außerdem möchten wir, dass das Geburtsdatum des Kindes nur angegeben wird, wenn der Name des Kindes eingegeben wurde.

Also schreibe ich eine benutzerdefinierte Validierung erforderlich. Wenn die Eingabe eine boolesche Eingabe erhält, muss das Steuerelement einen Wert haben, wenn die Eingabe wahr ist.

Das ist ein sehr einfacher Validator:

Und hier ist meine Form:

Wenn ich bei dieser Implementierung das Kontrollkästchen "Keine Kinder" aktivieren oder deaktivieren möchte, ohne das Steuerelement zu berühren, wird der Validierungsstatus nicht geändert.

Hier ist das gebrochene Verhalten:

Die Kontrolle der untergeordneten Namen bleibt auch dann ungültig, wenn ich das Kontrollkästchen "Keine untergeordneten Namen" aktiviert habe. Angular weiß nicht, ob eine erneute Überprüfung erforderlich ist.

Das gleiche gilt für das Geburtsdatum, da anfangs der Name leer war und dann das Geburtsdatum gültig war, auch wenn ich den Namen ausfülle. und ich erwarte, dass das Geburtsdatum jetzt ungültig ist.

Der Kontrollvalidierungsstatus wird nur geändert, wenn der Kontrollwert geändert wird, nicht, wenn die Validierungseingabe geändert wird.

Was wird der Hack sein?

Sehen wir uns die Validator-Oberfläche an:

Was ist der Zweck der zweiten Methode?

Diese Methode ist ein Endpunkt für die Funktion Angular to Register Validation Changes für die Validator-Implementierung, und der Validator kann sie aufrufen, wenn er eine geänderte Validierung auslösen möchte, z. B. wenn die Validierungseingabe geändert wird.

Implementieren wir dies in unserem Validator:

Wenn es eine Änderung in der Anweisungseingabe erfordert, rufen wir das this._onChange () auf, das uns im Winkel registriert hat. und dann weiß eckig, dass es erneut überprüft werden muss und der Status geändert wird.

Jetzt funktioniert es. Folgen Sie der roten Rahmenfarbe, die auf ein ungültiges Feld hinweist, und stellen Sie fest, dass es ungültig und gültig wird, auch wenn ich es nicht berühre.

Siehe vollständiges Codebeispiel

Überprüfen Sie die Winkelinvalidierung. und stellen fest, dass sie sie wie oben beschrieben implementieren. zum Beispiel maxLength:

Reaktive Form

So weit so gut, aber wie wird es in reaktiver Form funktionieren? Wenn ich keine Direktive habe, einfach validatorFn:

Das Problem, dass validationFn, mit dem ich das Formularsteuerelement erstelle, eine Funktion zurückgeben muss, die nur das Formularsteuerelement abrufen kann, bedeutet, dass keine Eingabe erfolgt. Die Eingabe kann im Abschluss definiert, aber nicht geändert werden.

Es sei denn, es handelt sich um eine veränderbare Objekteingabe.

Machen wir es zu einer veränderlichen Eingabe:

Wenn ich den requiredIf-Wert ändere, kann die Überprüfungsmethode mit dem aktualisierten Wert verwendet werden. Sie wird jedoch nicht widerrufen, wenn ich das Steuerelement in reaktiven Formen berühre. Ich kann den oben beschriebenen Hack nicht ausführen , weil ich überhaupt keine Direktive benutzt habe.
Die Methode, die ich gefunden habe, besteht darin, Eingabeänderungen zu registrieren und control.updateValueandValidity () aufzurufen, um den Validierungszyklus zu widerrufen.

Siehe ist ein Problem, das ich in Github geöffnet habe und das dieses Problem beschreibt.

Auch hier ist derselbe Code in der reaktiven Form sehr komplex, ich hoffe das obige Problem wird gelöst und es wird einfacher.