Bis inkl. Version 1.2 mussten Entwickler Parser bereitstellen, um eigene Validierungsregeln zu implementieren. Seit Version 1.3 gibt es parallel dazu ein eigenes Validator-Konzept. Da sich dieses Konzept auf das Validieren von Eingaben beschränkt, ist es etwas einfacher zu nutzen. Darüber hinaus bietet dieses neue Konzept auch die Möglichkeit, Validierungsregel asynchron zu prüfen. Das ist vor allem dann nützlich, wenn hierzu ein HTTP-basierter Service anzustoßen ist. Dieser Beitrag geht zunächst auf einfache Validatoren, welche ihre Arbeit synchron verrichten, ein. Ein weiterer Beitrag wird sich ihren asynchronen Gegenstücken zuwenden.
Wie bei Formatter und Parser registriert der Entwickler auch Validatoren bei ng-model über eine benutzerdefinierte Direktive (siehe nächstes Listing). Hierzu nutzt die Direktive die von ngModel angebotene Eigenschaft $validators. Hinter dieser Eigenschaft steht ein Objekt, dessen Eigenschaften auf Validatoren verweisen. Die Namen dieser Eigenschaften sind die Namen der Validierungsregeln. Bei den Validatoren handelt es sich um Funktionen, die den zu validierenden Wert entgegennehmen und einen Boolean, der über das Ergebnis der Validierung informiert, retournieren. Der Wert true zeigt hierbei an, dass die Validierung erfolgreich verlaufen ist; false lässt hingegen auf einen Verstoß gegen die jeweilige Validierungsregel schließen. Das nachfolgende Listing gezeigte Beispiel demonstriert dies anhand eines Validators, der eine Flugnummer unter Verwendung eines regulären Ausdrucks validiert.
app.directive(flugnrValidator, function() {
var pattern = /^\w+\d{3,}$/;
return {
require: ngModel,
link: function (scope, element, attrs, ngModel) {
ngModel.$validators.flugnr = function(value) {
var ok = value.match(pattern);
if(ok) return true;
return false;
}
}
}
});
Das Beispiel im nächsten Listing zeigt, wie der Entwickler einen solchen Validator anwenden kann. Dazu spendiert es dem zu validierenden Eingabefeld ein Attribut flugnr-validator, welches die zuvor betrachtete Direktive aktiviert. Dabei fällt auf, dass die Schreibweise zwischen dem Direktivennamen und dem Attributnamen ein wenig abweicht. Während die Direktive den Namen flugnrValidator hat, nennt sich das Attribut flugnr-validator. Hierbei berücksichtigt AngularJS die üblichen Namenskonventionen in JavaScript und HTML: In JavaScript kommt Camel-Case zum Einsatz und HTML-Bezeichner sind in Kleinbuchstaben gehalten und verwenden ein Minus als Worttrennzeichen. Um zu ermitteln, ob eine Fehlermeldung anzuzeigen ist, prüft das betrachtete Beispiel die Eigenschaft form.flugNummer.$error.flugnr, wobei flugnr dem Namen des Validators und somit dem Namen der hierdurch ausgedrückten Validierungsregel wiederspiegelt.
<div ng-app="flug">
<form ng-controller="editFlugCtrl" name="form" id="form">
<div class="form-group">
<label for="fnr">Flug-Nummer</label>
<div><input class="form-control"
ng-model="vm.flug.flugNummer"
required
flugnr-validator
name="flugNummer"
id="flugNummer" /></div>
<div ng-show="form.flugNummer.$error.required">Pflichtfeld!</div>
<div ng-show="form.flugNummer.$error.flugnr">Keine gültige Flugnummer!</div>
</div>
</form>
</div>
Registriert der Entwickler für eine Instanz von ng-model sowohl Parser als auch Validatoren, so führt AngularJS zunächst sämtliche Parser aus und wendet sich erst danach den Validatoren zu.