typescript - Hur skapar jag en egen valideringsdirektiv (dvs. attribut för validering) i Angular 2.0?
Jag arbetar på ett litet projekt för Angular 2.0 med TypeScript. Just nu, enligt min förståelse, har inte Angular 2.0 inbyggda validatorer för "min" och "max"-taggar. Jag förstår hur man kan skapa en egen validator och fästa den med FormBuilder, men jag vill se hur man kan skapa en egen validator-direktiv som jag kan fästa på ett attribut. HTML ser ut så här:
<div class="unit">
<div class="label">Age (13 - 120):</div>
<div class="labelTarget">
<input id="ageFrm" min="13" max="120" type="number" required=""
ng-control="age" #age="form" [class.error]="!age.valid"
[(ng-model)]="ageValue"/> {{age.valid}}
</div>
</div>
Just nu är age.valid alltid true eftersom det inte finns några validatorer för min och max. Jag försökte skapa mina egna. Först de anpassade valideringsfunktionerna:
import {Control} from "angular2/angular2";
export class HealthAppCustomValidators {
static min(min: number): Function {
return (control: Control): {[key: string]: any} => {
var v: number = Number(control.value);
console.log("validating " + v + " against " + min);
return v < min ?
{"min": {"requiredMin": min, "actualMin": v}} :
null;
};
}
static max(max: number): Function {
return (control: Control): {[key: string]: any} => {
var v: number = Number(control.value);
return v > max ?
{"max": {"requiredMax": max, "actualMax": v}} :
null;
};
}
}
Och sedan direktiven (detta är baserat på att granska källkoden):
import {Attribute, Control, Directive, forwardRef, Provider, NG_VALIDATORS} from "angular2/angular2";
import {HealthAppCustomValidators} from "./customValidators";
const MIN_VALIDATOR = new Provider(NG_VALIDATORS, {useExisting:
forwardRef(() => MinValidator), multi:true});
@Directive({
selector: '[min][ng-control],[min][ng-form-control],[min][ng-model]',
providers: [MIN_VALIDATOR]
})
export class MinValidator {
private _validator: Function;
constructor(@Attribute("min") min: string) {
console.log(min);
this._validator = HealthAppCustomValidators.min(Number(min));
}
validate(c: Control): {[key: string]: any} {
console.log("validate");
return this._validator(c);
}
}
Men varje gång jag faktiskt importerar direktiven misslyckas sidladdningen med följande fel:
TypeError: validator is not a function
at http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:12990:24
at Array.reduce (native)
at Function.ListWrapper.reduce (http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:4206:19)
at http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:12989:44
at http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:12990:24
at Array.reduce (native)
at Function.ListWrapper.reduce (http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:4206:19)
at Control.validator (http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:12989:44)
at Control.AbstractControl.updateValidity (http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:18871:27)
at http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:14097:14
All hjälp med rätt sätt att göra detta utan FormBuilder uppskattas mycket:
Svar #1
Som föreslagits av Jeremy,
problemet är löst sedan alpha 45 där de lade till stöd för Validator. Felmeddelandet kan dock vara förvirrande (du angav en funktion, varför fungerade det inte?) men commit-meddelandet ger en ledtråd
För närvarande är det enda sättet för en direktiv att exportera en validator genom att tillhandahålla en funktion. Detta gör det besvärligt att skriva validatorer som är beroende av direktivets indata. Förutom att stödja funktioner som validatorer, stöds även klasser som implementerar Validator-gränssnittet.
Jag kunde inte hitta exempel på anpassade validatorer i alpha 44 eller tidigare, så jag kan inte säga hur de fungerade då. Och det är mest sannolikt att de uppdaterade alla sina exempel och fungerande validatorer för att fungera med alpha 45 och senare.
Hur som helst, detta löstes genom att uppgradera Angular2 till den senaste versionen (alpha 48 är förresten den senaste, jag skrev alpha 47 i kommentaren, mitt misstag) även om det krävdes åtminstone alpha 45.