• 29. März 2016

Parametrisierbare Validierungs-Attribute mit Angular 2 erstellen

Angular 2 bietet wie sein Vorgänger auch die Möglichkeit zur deklarativen Angabe von Validierungsregeln. Beispielsweise kann eine Anwendung mit den Attributen minlength und maxlength eine Längenbegrenzung für Felder festlegen:

<input [(ngModel)]="von" minlength="3" maxlength="30">

In diesem Beitrag zeige ich, wie man diese Möglichkeit für eigene Validierungsregeln nutzen kann. Dazu dazu genutzte Beispiel findet sich auch in meinem Demo-Projekt unter [1].

Validierungs-Regel implementieren

Eine Validierungsregel ist in Angular 2 zunächst lediglich eine Funktion, die ein Control-Objekt entgegen nimmt und ein Fehlerbeschreibungsobjekt retourniert. Das Fehlerbeschreibungsobjekt beinhaltet für jeden entdeckten Validierungsfehler eine Eigenschaft. Die Anwendung kann später den Schlüssel dieser Eigenschaften abfragen, um sich über den Ausgang der Validierung zu informieren. Konnte die Validierungsfunktion keinen Fehler entdecken, liefert sie ein leeres Objekt retour.

Eine parametrisierbare Validierungsregel lässt sich als Funktion höherer Ordnung repräsentieren. Diese nimmt die gewünschten Parameter entgegen und retourniert dafür eine Funktion mit den zuvor erwähnten Eigenschaften.

Das nachfolgende Beispiel zeigt eine solche Funktion, welche den Wertebereich einer Zahl prüft:

import {Control} from 'angular2/common';

export class RangeValidator {

    static create(min: number, max: number): Function {
        return (c: Control): any => {
            if (!c.value) return {};

            var value = Number(c.value);

            if (isNaN(value)) return {'range': true};
            if (value >= min && value <= max) return {};

            return {'range': true};
        };
    }

}

Attribut für parametrisierbare Validierungsregel

Um eine Validierungsregel als Attribut bereitzustellen, ist eine Direktive einzurichten. Das nachfolgende Beispiel demonstriert den Aufbau solch einer Direktive. Sie erhält für jeden Parameter der Validierungsfunktion ein Konstruktorargument. Diese Argumente beziehen ihre Werte aus den gewünschten Attributen. Zum Festlegen der Namen dieser Attribute kommt der Dekorator @Attribute zum Einsatz. Mit diesen Werten und der oben gezeigten Funktion erzeugt der Konstruktor die parametrisierte Validierungs-Funktion. Darüber hinaus implementiert die Direktive das Interface Validator und die davon vorgegebene Methode validate, welche an die Validierungs-Funktion delegiert.

Um festzulegen, auf welche Eingabefelder die Validierungsregel anzuwenden ist, erhält die Direktive einen Selektor. Demnach kommt die Direktive bei input-Elementen, die sowohl das Attribut min als auch das Attribut max aufweisen, zum Einsatz. Für diese Elemente bindet sich die Direktive selbst an das Token NG_VALIDATORS. Da jedes Feld mehrere Validierungsregeln aufweisen kann, kommt hierzu per Definition ein Multi-Binding zum Einsatz. Dies zeigt auch schön, wie Angular 2 intern deklarative Validierungen abarbeitet: Es zieht pro Feld per Dependency Injection alle an NG_VALIDATORS gebundenen Validatoren heran und bringt sie zum Ermitteln des Validierungsergebnisses zur Ausführung.

import {Directive, provide, Attribute} from 'angular2/core';
import {Control, NG_VALIDATORS, Validator} from 'angular2/common';

@Directive({
  selector: 'input[min][max]',
  providers: [provide(NG_VALIDATORS, {useExisting: RangeValidatorDirective, multi: true})]
})
export class RangeValidatorDirective implements Validator {

    validator: Function;

    constructor(@Attribute('min') min: number, @Attribute('max') max: number) {
        this.validator = RangeValidator.create(min, max);
    }

    validate(c: Control) {
        return this.validator(c);
    }

}

Validierungs-Attribut nutzen

Zum Anwenden der Validierungsregel ist die entwickelte Direktive bei der Komponente der Wahl zu registrieren:

@Component({
    templateUrl: 'app/flug-edit/flug-edit.html',
    directives: [RangeValidatorDirective]
})
export class FlugEdit  {
    [...]
}

Alternativ dazu kann die Anwendung die Direktive auch beim Bootstrapping global registrieren. Dazu verknüpft sie sie über ein Multi-Binding mit dem Token PLATFORM_DIRECTIVES:

import {PLATFORM_DIRECTIVES} from 'angular2/core';

[...]

var services = [
    [...]
    provide(PLATFORM_DIRECTIVES, {useValue: RangeValidatorDirective, multi: true})
];


bootstrap(App, services);

Danach kann die Direktive im Template der gewünschten Komponente genutzt werden. Dazu ist lediglich ein Element, das zum festgelegten Selektor passt, einzurichten. Im betrachteten Fall handelt es sich dabei um ein input-Element mit den Attributen min und max.

Um herauszufinden, ob die Validierungs funktioniert hat, nutzt das Template die Methode hasError des Controls. Dabei übergibt sie jenen Schlüssel, der im Fehlerbeschreibungsobjekt den Validierungsfehler repräsentiert. Im hier gezeigten Fall ist das der Schlüssel range.

<form #f="ngForm">
<div class="form-group">
    <label>Id: </label>
    <input [(ngModel)]="flug.id" ngControl="id" class="form-control" min="0" max="9999">
    <div *ngIf="f.controls.id?.hasError('range')">
        Wert muss zwischen 0 und 9999 liegen!
    </div>
</div>
</form>

[1] https://github.com/manfredsteyer/forms-sample-jm-2016-03

 

 
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 ...