typescript - Hur man tillhandahåller asynkront parameter till anpassade Angular-validerare
Jag håller på att sätta upp formulärvaliderare där min och max för flera fält hämtas via ett enda API. Appen kraschar när man försöker skicka ett av dessa asynkrona värden till en parameter i en anpassad validator, men det fungerar när värdet är hårdkodat.
Felet som uppstår när ett asynkront värde skickas är följande:
FEL Fel: formGroup förväntar sig en FormGroup-instans. Vänligen skicka en.
fil.ts:
export class PackageDimensionValidator {
static validSize(min: number, max: number): ValidatorFn {
return (control: AbstractControl): { [key: string]: boolean } | null => {
if (control.value !== undefined && (isNaN(control.value) || control.value < min || control.value > max)) {
return { 'exceedRange': true };
}
return null;
};
}
}
// ...
ngOnInit() {
// Retrieve maximum package dimensions for input data validation.
this.shipmentService.getMaxPackageSize()
.subscribe(result => {
this.packageRestrictions = new PackageRestrictions(result);
console.dir(this.packageRestrictions);
this.setupPackageValidators();
});
}
setupPackageValidators() {
const maxWidth = this.packageRestrictions.maxWidth; // Crashes on Async value.
// const maxWidth = 5; // Works on hard-coded value.
// Setup package dimension validators.
this.packageSizeForm = this.formBuilder.group({
maxWidth: new FormControl('', Validators.compose([
PackageDimensionValidator.validSize(null, maxWidth),
// Other validators ...
]))
});
}
fil.html:
<form [formGroup]="packageSizeForm">
<input formControlName="maxWidth" type="text" required />
</form>
Idealiskt sett kommer det att finnas flera formControls var och en med unika min- och maxvärden, alla hämtade samtidigt av en enda API. Tankegången var att anropa den API:n, lagra dess resultat lokalt och sedan bygga formulärvaliderare. Jag ifrågasätter nu ordningen på denna sekvens.
Svar #1
Jag är inte helt säker på att felmeddelandet du får speglar det problem du beskrev. Jag skulle börja med att initiera packageSizeForm i din ngOnInit utan validerare:
ngOnInit() {
this.packageSizeForm = new FormGroup({
maxWidth: new FormControl('');
});
this.shipmentService.getMaxPackageSize()
.subscribe(result => {
this.packageRestrictions = new PackageRestrictions(result);
console.dir(this.packageRestrictions);
this.setupPackageValidators();
});
}
Sätt sedan validators i this.setupPackageValidators();:
setupPackageValidators() {
this.packageSizeForm.get('maxWidth').clearValidators();
this.packageSizeForm.get('maxWidth').setValidators(Validators.compose([
PackageDimensionValidator.validSize(null, maxWidth)]);
this.packageSizeForm.get('maxWidth').updateValueAndValidity();
}
Svar #2
Du kanske vill använda asynkrona validatorer
https://angular.io/api/forms/AsyncValidator
asyncValidator skickas som en valfri tredje parameter till FormControl-konstruktorn:
class FormControl {
...
constructor(
formState: any = null,
validatorOrOpts?: ValidatorFn | AbstractControlOptions | ValidatorFn[],
asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[]
)
...
}
