Ein sehr häufig vorkommendes Szenario bei der Arbeit mit Fomularen ist die Umwandlung von Werten, also die Konvertierung zwischen Formular- und Daten-Repräsentation. In Angular ist dies mit einer Direktive möglich die das Interface ControlValueAccessor implementiert.
Als Beispiel dient ein sehr simples Beispiel. In unserem Datenmodel werden Namen als separates Objekt mit den Attributen „firstname“ und „lastname“ abgelegt. Innerhalb unsere Formulares sollen diese Werte jedoch gemeinsam (mit Leerzeichen getrennt) eingegeben werden:
Der Schlüsselpunkt ist das Interface ControlValueAccessor mit dessen Hilfe wir unsere eigene Zugriffsmethode auf Eingabefelder realisieren können (in diesem Beispiel verwenden wir es als Konverter, dieses Interface würde aber z.B. auch bei der Erstellung einer völlig eigenen Eingabekomponente verwendet werden).
@Directive({ selector: '[nameConverter]', providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NameConverterDirective), multi: true } ] }) export class NameConverterDirective implements ControlValueAccessor {...}
Hier deklarieren wir eine entsprechende Directive, die wir an die Liste der Angular zur Verfügung stehenden Value-Accessoren anhängen.
Zur Implememtierung müssen wir nun noch die entsprechenden Methoden implementieren, die im Kern diese beiden sind:
- writeValue(value: any), vom Model in die View
- HostListener, um auf Änderungen in der View zu reagieren
writeValue(value: any) { let val = ''; if (value && value.firstname && value.lastname) { const name: Name = value; val = name.firstname + ' ' + name.lastname; } this._renderer.setProperty(this._elementRef.nativeElement, 'value', val); } @HostListener('input', ['$event']) onInput(event: any) { const namesp = event.target.value.split(' ', 2); const targetValue = new Name(namesp[0], namesp.length == 1 ? '' : namesp[1]); this.onChangeMethod(targetValue); }