So schreiben Sie benutzerdefinierte Formularsteuerelemente in Angular

Wir alle lieben bidirektionale Datenbindungen, oder? Wir lieben es, wenn wir einigen Eingaben die Direktive "NgModel" hinzufügen und alle Wertänderungen synchronisieren. Es ist eine wirklich coole Funktion. Es wurde jedoch interessant, wenn wir diese Funktionalität zu unserer benutzerdefinierten Komponente hinzufügen möchten, z. B. zu einer solchen Komponente

Wir haben also zwei Schaltflächen, und wenn wir auf Plus klicken, wird sie um eine erhöht, und wenn wir auf Minus klicken, wird sie um eine verringert. Wir möchten diese Komponente überall verwenden und möchten ngModel zu dieser Komponente hinzufügen, damit wir den Wert aus dem Modus festlegen können und wenn ein Benutzer auf eine Schaltfläche klickt, wird er entsprechend dem Modell aktualisiert.

Unsere Komponentenvorlage sieht so aus

Okay, versuchen wir, diese Komponente irgendwo zu verwenden und fügen ngModel hinzu.

   
Aktualisieren Sie Ihr Bargeld.    

Okay, wir rennen und bekommen diesen Fehler

hmmm, okay die harte. Der Wert accessor (wir wissen nicht, was das ist) für die Formularsteuerung (wir wissen es auch nicht) mit einem nicht angegebenen Namensattribut (ja, wir kennen das Namensattribut). es heißt bla bla… name attribute, also könnten wir denken, dass, wenn wir name attribute hinzufügen, alles funktionieren wird. Versuchen wir hinzuzufügen und zu sehen, was passiert

   
Aktualisieren Sie Ihr Bargeld.    

Wenn wir es ausführen, werden wir das nächste Ergebnis haben

Okay und jetzt sind wir verloren. „Kein Value Accessor für die Formularsteuerung mit dem Namen„ cash “ist nicht einfacher als der vorherige.

Wie wir herausfinden, gibt es dort nichts Schwieriges, aber bevor ich erkläre, wie man diesen Fehler behebt, möchte ich Ihnen zeigen, wie eckig / Formen unter der Haube funktionieren und warum es diesen Wert-Accessor benötigt.

Kontrollwert-Accessor

Für jede native HTML-Eingabe, die Sie in Angular verwenden (Eingabe, Textbereich, Auswahl, Kontrollkästchen), wird eine Direktive verwendet, die die Control Value Accessor-Schnittstelle unter der Haube für die Arbeit mit ngModel implementiert. Diese Direktive ist für das Schreiben von Daten vom Modell zur Ansicht und verantwortlich Umgekehrt, wenn Sie also die einfachste Eingabe wie diese verwenden,

Angular fügt diesem Eingang eine Direktive unter der Haube hinzu. Immer wenn Updates vom Modell kommen, sagt ngModel, dass der neue Wert von hay control value accessor vom Modell übernommen wird. Control Value Accessor aktualisiert die Ansicht und wenn der Benutzer etwas ändert, sagt Control Value Accessor zu ngModel, dass der neue Wert vom Benutzer übernommen wird.

Der Einfachheit halber werde ich Ihnen zeigen, wie tatsächlich eine eckige Direktive hinzugefügt wird, sodass Sie vermuten, dass dort nichts Magisches vor sich geht.

Das ist Angular-Quellcode

Lassen Sie mich das klären. Jedes Mal, wenn Angular eine Eingabe vom Typ Zahl mit dem Attribut ngModel sieht, wird diese Anweisung zu dieser Eingabe hinzugefügt. Diese Direktive implementiert die ControlValueAccessor-Schnittstelle, für die 4 Methoden implementiert werden müssen

  • WriteValue
  • RegisterOnChange
  • RegisterOnTouched
  • SetDisabledState

Die wichtigsten sind WriteValue, RegisterOnChange

  • WriteValue

Diese Methode wird aufgerufen, wenn der Wert außerhalb geändert wird. Beispielsweise haben wir den Bargeldbetrag von app.component auf 5 geändert. Anschließend wird diese Methode aufgerufen und hat den Wert 5 als Parameter. Diese Anweisung aktualisiert den Eingabewert entsprechend.

  • RegisterOnChange

Es sieht etwas kompliziert aus, ist aber so einfach wie WriteValue. Die RegisterOnChange-Funktion wird einmal pro Initialisierung aufgerufen, und Sie müssen nur die übergebene Referenzfunktion speichern. Wenn sich also der Wert in der Ansicht ändert, rufen Sie diese Funktion auf und übergeben einen neuen Wert. NgModel wird entsprechend aktualisiert.

Um ngModel zu unserer benutzerdefinierten Komponente hinzuzufügen, müssen wir ControlValueAccessor implementieren. Als letztes müssen wir diese Komponente zum Provider-Array "NG_VALUE_ACCESSOR" hinzufügen. Dies liegt daran, dass bei jeder Initialisierung der ngModel-Direktive das Provider-Array NG_VALUE_ACCESSOR verwendet wird, um den aktuellen Zugriffswert abzurufen, an dem er gerade arbeitet. Hier ist der Konstruktor ngModel

So wird die Direktive NG_VALUE_ACCESSOR wie folgt hinzugefügt

Benutzerdefinierte Formularsteuerung

Okay, lassen Sie uns zum Schluss unser benutzerdefiniertes Formularsteuerelement erstellen

Ich denke, die Erklärung des Codes ist extra dafür. Wenn wir jetzt unsere Komponente verwenden, können wir ihr einfach die ngModel-Direktive hinzufügen