GEDOPLAN
Webprogrammierung

[deprecated]Angular 2 – Konverter ($parsers and $formatters)

Webprogrammierung

Der folgende Abschnitt ist veraltet!In der aktuellen Version ist folgendes Vorgehen zu verwenden:

https://javaeeblog.wordpress.com/?p=4409

Angular 2 steht in den Startlöchern bereit, wenn auch erst in einer frühen Beta-Phase. Zeit genug also sich mit der neuen Welt von Anuglar JS vertraut zu machen. Bei den ersten Schritten stolpert man sehr schnell über die Frage: Wie findet eine Konvertierung von Daten zwischen View und Modell statt? In Angular1 standen uns hierfür $formatters und $parsers zur Verfügung, in Angular2 gibt es dazu bisher kein offizielles Konzept (siehe GitHub ). Aber werfen wir einen Blick auf die Möglichkeiten die sich uns heute schon bieten…

 

Das typische Binding einer Eingabe Komponente in Angular 2 sieht bekanntlich so aus:

<input id="datefield" [(ngModel)]="recordService.record.startTime" />

Durch die doppelte Klammerung („[(….)]“, alternativ: „onbind-ngModel“) zusammen mit der „ngModel“-Direktive führen wir an dieser Stelle ein Two-Way-Binding ein mit dessen Hilfe die Werte unseres Models in der View angezeigt und Änderungen zurück gespielt werden. Nutzen wir dieses Vorgehen auch für ein Datenfeld vom Typ „Date“ führt dies dazu, dass wir in der Anzeige die unansehnliche String Repräsentation eines Date-Objektes finden, das bei Änderungen zu allem Überfluss auch noch als String zurück ins Model geschrieben wird. Ein Converter / Parser muss also her. $parsers und $formatters aus Angular 1 haben (bisher?) ihren Weg noch nicht in den Version 2. geschafft, dennoch gibt es mit den bestehenden Mittel die Möglichkeit eine solche Funktion zu implementieren: eine eigene Direktive:

(hier einmal die gesamte Implementierung in TypeScript, im Folgenden werde wir auf die einzelnen Punkte eingehen)

import {Directive, Renderer, ElementRef} from 'angular2/core'
import {NgModel, DefaultValueAccessor} from 'angular2/common'

@Directive({
selector: '[tsdate]',
host: {
    '(change)': 'onChanges($event.target.value)'
}
})
export class DateDirective extends DefaultValueAccessor {

constructor(private model: NgModel, private el: ElementRef, private renderer: Renderer) {
    super(renderer, el);
    model.valueAccessor = this;
}

writeValue(obj: Date): void {
    if (obj) {
        super.writeValue(this.formatDate(obj));
    }
}

onChanges(value: string) {
    this.onChange(this.parseDate(value));
}

formatDate(inputDate: Date): string {
    // Datum formatieren
    return ...
}

parseDate(inputString: string): Date {
 // Datum parsen
 return ...Date...
}
}

Mittels des TypeScript Decorators „Directive“ erzeugen wir hier eine Direktive die später an HTML Elemente angehängt werden kann. Über welche Property dies geschieht legen wir durch das selector Attribut fest: selector: ‚[tsdate]‘, Verwendung: . Als weiteren Schritt wollen wir geänderte Eingaben des Textfeldes auf dem die Direktive verwendet werden soll mit einer entsprechenden Methode versehen um darauf zu reagieren. Mit Hilfe des „host“ Attributes registrieren wir uns auf das entsprechende „change“-Event des übergeordneten HTML Elements (in unserem Fall: „input“) um zusammen mit dem Wert des Textfeldes als Parameter eine unserer Methoden auf zu rufen.

Die eigentliche Implementierung unserer Logik findet in der anschließend deklarierten Klasse statt:

export class DateDirective extends DefaultValueAccessor

Dabei erben wir von der Angular zur Verfügung gestellten Klasse: DefaultValueAccessor (implements ControlValueAccessor). Diese Klasse wird von der NgModel-Direktive verwendet um Änderungen ins Model zurück zu schreiben und auf Eingaben des Benutzers zu reagieren.

constructor(private model: NgModel, private el: ElementRef, private renderer: Renderer) {
    super(renderer, el);
    model.valueAccessor = this;
}

Innerhalb des Konstruktors lassen wir uns unter anderem das NgModel injizieren mit dessen Hilfe wir das Ein- und Ausgabeverhalten der Direktive anpassen werden. Dazu ändern wir den valueAccessor auf die aktuelle Klasse um die von uns benötigten Methoden zu überschreiben und nach Bedarf an zu passen.

Die beiden entscheidenen Methoden die wir  dazu nutzen sind:

writeValue(obj: Date): void

Die „writeValue“ Methode wird aufgerufen um einen Wert aus dem Model in die View zu übertragen. An dieser Stelle greifen wir ein und nehmen das Date-Objekt aus dem Model um es in eine für uns angenehme String-Repräsentation zu bringen. Das eigentliche setzen des value-Attributes des Textfeldes überlassen wir dann der Standard Implementierung.

onChanges(value: string)

Wie in der Konfiguration angegeben wird diese Methode bei Änderungen des Textfeldes aufgerufen und mit dem geänderten Wert versorgt. An dieser Stelle führen wir die Umwandlung des Strings in ein echtes JavaScript Datum durch, um zum Abschluss erneut die Standard Implementierung dafür zu bemühen diesen Wert ans Model zu übertragen

Wie wir sehen konnten besteht auch mit den in der Beta-Version zur Verfügung gestellten Mitteln eine recht übersichtliche Möglichkeit einen Konverter/Parser zu implementieren. Ob dieses Vorgehen in dieser Form auch in Zukunft Verwendung findet oder es eine ergänzendes Konzept in Angular 2 geben wird muss sich zeigen.

Das Beispiel findet sich noch einmal hier in seiner gesamten Form: github

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren.

Autor

Diesen Artikel teilen

LinkedIn
Xing

Gibt es noch Fragen?

Fragen beantworten wir sehr gerne! Schreibe uns einfach per Kontaktformular.

Kurse

weitere Blogbeiträge

flasks 606612 640
Web Security, Webprogrammierung

Keycloak + Protractor E2E Test

Keycloak ist eine charmante Authentifizierungs-Lösung die sich dank keycloak-angular relativ Problemlos in der eigenen Anwendung verankern lässt. Im Arbeitsalltag stolpert…

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!