• 11. Januar 2016

Parser und Formatter in Angular 2

AngularJS 1.x erlaubt mit seinem Parser-Konzept das Verarbeiten von Benutzereingaben, bevor ng-model sie über die Datenbindung ans Model zurückschreibt. Analog dazu können Formatter gebundene Daten aus dem Model formatieren, bevor sie in einem Eingabefeld aufscheinen.

In Angular 2 gibt es solch ein Konzept nicht - zumindest nicht auf den ersten Blick. Allerdings findet man hier das Konzept der ValueAccessor. Dabei handelt es sich um Klassen, die für die Synchronisation zwischen Steuerelementen und dem Model zuständig sind. Da unterschiedliche Steuerelemente, wie Checkboxes oder Eingabefelder, hierbei unterschiedlich zu nutzen sind, gibt es auch verschiedene ValueAccessor-Implementierungen.

Für eigene Implementierungen bietet sich u. a. das Interface. ControlValueAccessor an. Es definiert die Methoden registerOnChange sowie registerOnTouched, welche von Angular Callbacks übergeben bekommen. Diese nutzt der Value-Accessor um geänderte Daten zum Controller zurückzusenden. Sie sind nach Änderungen im jeweiligen Steuerelement oder beim Verlassen des Steuerelements anzustoßen. Daneben gibt das Interface die Methode writeValue vor. Sie bekommt von Angular Werte aus dem Model, welche es in das Steuerelement zu schreiben gilt.

Das nachfolgende Beispiel demonstriert, wie Entwicklungs-Teams damit die gebundenen Daten im Rahmen der Datenbindung modifizieren können. Es wandelt ein Datum, das im Model als ISO-String vorliegt, in ein deutsches Datum um und schreibt Modifikationen an diesem Datum in Form eines ISO-Strings ins Model zurück.

Um das Zurückschreiben ins Model zu beeinflussen, richtet das betrachtete Beispiel Event-Handler für das input- und das blur-Event des Host-Steuerelements ein. Beim Host-Steuerelement handelt es sich beispielsweise um ein Eingabefeld (<input>) oder eine Textarea. Diese definiert es über die Eigenschaft host des Directive-Dekorators. Der Event-Handler für input modifiziert die Eingaben durch Aufruf des zuvor besprochenen Callbacks onChange.

Zum Beeinflussen der im Steuerelement präsentierten Daten überschreibt das Beispiel die Methode writeValue. Sie kümmert sich um die Formatierung und delegiert anschließend an die Basis-Implementierung von writeValue, welche ins Steuerelement schreibt, weiter.

Über die Eigenschaft selector gibt die Implementierung bekannt, für welche Elemente sie zu nutzen ist. Der Wert input[date] adressiert dabei input-Elemente mit einem date-Attribut, beispielsweise <input date [(ng-model)]="datum">.

Damit Angular 2 die Direktive tatsächlich als ValueAccessor nutzt, ist ein Provider einzurichten, der sie ans Token NG_VALUE_ACCESSOR bindet. Zur Laufzeit ruft Angular 2 sämtliche Elemente, die an dieses Token gebunden wurden, ab und nutzt sie zur Datenbindung beim jeweiligen Element. Die beim Definieren des Providers hinterlegte Angabe multi: true sagt aus, dass mehrere Elemente an NG_VALUE_ACCESSOR gebunden sein dürfen. Die Indirektion über forwardRef löst das Henne-Ei-Problem, das durch die gegenseitige Referenzierung zwischen dem Provider und dem ValueAccessor entsteht.

import {Directive, Renderer, ElementRef, Self, forwardRef, provide} from '@angular/core';
import {NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

@Directive({
    selector: '[mydate]',
    host: {'(input)': 'input($event.target.value)', '(blur)': 'blur()'},
    providers: [{
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() => DateValueAccessor),
        multi: true}]
})
export class DateValueAccessor implements ControlValueAccessor {

    onChange = (_: any) => {};
    onTouched = () => {};

    constructor(private _renderer: Renderer, private _elementRef: ElementRef) {}

    registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
    registerOnTouched(fn: () => void): void { this.onTouched = fn; }


    blur() {
        this.onTouched();
    }

    // Parser: View --> Ctrl
    input(value) {

        // Write back to model
        if (value) {
            value = value.split(/\./);
            value = value[2] + "-" + value[1] + "-" + value[0];
        }

        this.onChange(value);
    }

    // Formatter: Ctrl --> View
    writeValue(value: any): void {

        // Write to view
        if (value) {
            var date = new Date(value);

            value =
                date.getDate() + "."
                    + (date.getMonth()+1) + "."
                    + date.getFullYear();
        }

        var normalizedValue = (value) ? value : '';
        this._renderer.setElementProperty(this._elementRef.nativeElement, 'value', normalizedValue);

    }

}

 

 
Hier können Sie eine Anfrage für eine unverbindliche Schulung ode Beratung bzw. einen Workshop erstellen.
 
Unverbindliche Anfrage
 
 

Schulungen

Angular Schulung: Strukturierte Einführung

Lernen Sie in dieser interaktiven Schulung anhand einer Beispielanwendung den Einsatz von Angular für Ihre erfolgreichen Projekte kennen. Sie durchdringen die Hintergründe und bauen von der ersten Minute an auf Best Practices auf.

Details

Advanced Angular: Enterprise-Anwendungen und Architektur

In dieser Schulung erfahren Sie alles für die Entwicklung großer Anwendungen mit Angular: Mono-Repos, Micro-Apps, State Management, Performance und mehr

Details

Angular: Strukturierte Einführung

Seit der Ankündigung von Angular (2+) fragen sich Entwicklungs-Teams, welche Migrationspfade für AngularJS-1.x-Anwendungen vorliegen werden. Das im Lieferumfang von Angular enthaltene ngUpgrade bietet eine Antwort darauf. Es erlaubt einen Parallelbetrieb von AngularJS 1.x und Angular (2+) und stellt somit die Grundlage für eine schrittweise Migration dar.

Details

Progressive Web-Apps mit Angular

Progressive Web Apps bieten den Komfort nativer Anwendungen, indem sie auf moderne Browser APIs, wie Service Worker, setzen. Sie sind installierbar sowie offlinefähig und nutzen Hintergrundprozesse für Datensynchronisation und Push-Notifications. Diese Schulung zeigt anhand eines durchgehenden Beispiels was sich genau hinter diesem neuen Konzept verbirgt, wie solche Anwendungen mit Angular entwickelt werden und wie Sie in Ihren Projekten von den dahinterstehenden Ideen profitieren.

Details

Reaktive Architekturen mit Angular und Redux

Dieses interaktive Seminar vermittelt, wie Sie reaktive Anwendungen mit Angular entwickeln können.

Details

TypeScript

TypeScript gibt Ihnen alle Möglichkeiten der neuen JavaScript-Standards und zusätzlich ein statisches Typsystem, das dabei hilft, Fehler möglichst früh zu erkennen. Außerdem ist TypeScript die Grundlage für Angular. In diesem interaktiven Seminar lernen Sie diese mächtige Sprache anhand einer Fallstudie kennen.

Details

Weitere Schulungen ...