validering - Min/Max-validerare i Angular 2 Final
Enligt thoughtgram.io är de för närvarande stödjda validatorerna:
- krävs
- minlängd
- maxlängd
- mönster
Så, med tanke på följande kod (plunkr här):
@Component({
selector: 'my-app',
template: `
<form #formRef="ngForm">
<input type="number" [(ngModel)]="firstValue" name="firstValue" min="0" required/>
<input type="text" [(ngModel)]="secondValue" maxlength="5" name="secondValue" required/>
<button type="submit"> Submit </button>
</form>
FORM: {{formRef.form | json }}
`
})
export class AppComponent {
firstValue = -22;
secondValue = "eyy macarena!";
}
Medan minlength stöds, ignoreras min="0" av Angular-validering:
Så, för att få formuläret att resultera i ett fel när firstValue ngModel < 0, behöver jag skapa en egen validator?
Svar #1
För att tillämpa min/max-validering på ett nummer behöver du skapa en anpassad validator
Validators-klassen har för närvarande bara några få validators, nämligen
- obligatorisk
- krävsSant
- minlängd
- maxlängd
- mönster
- nullValidator
- komponera
- composeAsync
Validator: Här är en nedtonad version av min nummervalidator, du kan förbättra den som du vill
static number(prms = {}): ValidatorFn {
return (control: FormControl): {[key: string]: any} => {
if(isPresent(Validators.required(control))) {
return null;
}
let val: number = control.value;
if(isNaN(val) || /\D/.test(val.toString())) {
return {"number": true};
} else if(!isNaN(prms.min) && !isNaN(prms.max)) {
return val < prms.min || val > prms.max ? {"number": true} : null;
} else if(!isNaN(prms.min)) {
return val < prms.min ? {"number": true} : null;
} else if(!isNaN(prms.max)) {
return val > prms.max ? {"number": true} : null;
} else {
return null;
}
};
}
Användning:
// check for valid number
var numberControl = new FormControl("", [Validators.required, CustomValidators.number()])
// check for valid number and min value
var numberControl = new FormControl("", CustomValidators.number({min: 0}))
// check for valid number and max value
var numberControl = new FormControl("", CustomValidators.number({max: 20}))
// check for valid number and value range ie: [0-20]
var numberControl = new FormControl("", CustomValidators.number({min: 0, max: 20}))
Svar #2
Jag hittade ett bibliotek som implementerar många anpassade validatorer - ng2-validation - som kan användas med template-drivna formulär (attributdirektiv). Exempel:
<input type="number" [(ngModel)]="someNumber" name="someNumber" #field="ngModel" [range]="[10, 20]"/>
<p *ngIf="someNumber.errors?.range">Must be in range</p>
Svar #3
Angular stöder nu min-/max-validatorer som standard.
Angular tillhandahåller följande validatorer som standard. Lägger till listan här så att nykomlingar enkelt kan lära sig vilka de nuvarande stödda standardvalidatorerna är och söka vidare på Google efter deras intresse.
- min
- max
- obligatorisk
- krävsSant
- e-post
- minLängd
- maxLängd
- mönster
- nullValidator
- komponera
- composeAsync
du kommer att få den kompletta listan över Angular-validerare
Hur man använder min/max-validator: Från dokumentationen av Angular -
static min(min: number): ValidatorFn
static max(max: number): ValidatorFn
min()/max() är en statisk funktion som tar ett nummer som parameter och returnerar en validatorfunktion som returnerar en felkarta med min/max-egenskapen om valideringskontrollen misslyckas, annars null.
använd min validator i formControl, (för mer information, klicka här)
const control = new FormControl(9, Validators.min(10));
använd max-validatorn i formControl, (för mer information, klicka här)
const control = new FormControl(11, Validators.max(10));
ibland behöver vi lägga till validator dynamiskt. setValidators() är räddaren. du kan använda det som följande -
const control = new FormControl(10);
control.setValidators([Validators.min(9), Validators.max(11)]);
Svar #4
Du kan enkelt implementera din egen validering (mallbaserad) genom att skapa en direktiv som implementerar Validator-gränssnittet.
import { Directive, Input, forwardRef } from '@angular/core'
import { NG_VALIDATORS, Validator, AbstractControl, Validators } from '@angular/forms'
@Directive({
selector: '[min]',
providers: [{ provide: NG_VALIDATORS, useExisting: MinDirective, multi: true }]
})
export class MinDirective implements Validator {
@Input() min: number;
validate(control: AbstractControl): { [key: string]: any } {
return Validators.min(this.min)(control)
// or you can write your own validation e.g.
// return control.value < this.min ? { min:{ invalid: true, actual: control.value }} : null
}
}
Svar #5
Jag letade efter samma sak nu, använde detta för att lösa det.
Min kod:
this.formBuilder.group({
'feild': [value, [Validators.required, Validators.min(1)]]
});
Svar #6
Såvitt jag vet, är det implementerat nu, kolla https://github.com/angular/angular/blob/master/packages/forms/src/validators.ts
Detta är den del som implementerar det du letar efter:
export class Validators {
/**
* Validator that requires controls to have a value greater than a number.
*/
static min(min: number): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) {
return null; // don't validate empty values to allow optional controls
}
const value = parseFloat(control.value);
// Controls with NaN values after parsing should be treated as not having a
// minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min
return !isNaN(value) && value < min ? {'min': {'min': min, 'actual': control.value}} : null;
};
}
/**
* Validator that requires controls to have a value less than a number.
*/
static max(max: number): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) {
return null; // don't validate empty values to allow optional controls
}
const value = parseFloat(control.value);
// Controls with NaN values after parsing should be treated as not having a
// maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max
return !isNaN(value) && value > max ? {'max': {'max': max, 'actual': control.value}} : null;
};
}
Svar #7
Tydligen hade Angular max-/min-direktiv för formulär som styrs av mallar vid någon tidpunkt men var tvungen att ta bort dem i v4.2.0. Du kan läsa om regressionen som orsakade borttagningen här: https://github.com/angular/angular/issues/17491
För tillfället är den enda fungerande lösningen som jag känner till att använda anpassad direktiv som @amd föreslog. Här är hur man använder det med Bootstrap 4.
min-validator.directive.ts
import { Directive, Input } from '@angular/core'
import { NG_VALIDATORS, Validator, AbstractControl, Validators } from '@angular/forms'
@Directive({
selector: '[min]',
providers: [{ provide: NG_VALIDATORS, useExisting: MinDirective, multi: true }]
})
export class MinDirective implements Validator {
@Input() min: number;
validate(control: AbstractControl): { [key: string]: any } {
return Validators.min(this.min)(control)
}
}
Och i din mall:
<input type="number" [min]="minAge" #age="ngModel" [(ngModel)]="person.age" class="form-control" [ngClass]="{'is-invalid':age.invalid}">
<div *ngIf="age.invalid && (age.dirty || age.touched)" class="invalid-feedback">You need to be older than {{minAge}} to participate</div>
Hoppas det här hjälper!

