问题
I migrated my project to angular 11 and I noticed that the global validations that I added make FormBuilder.group
deprecated with the message:
group is deprecated: This api is not typesafe and can result in issues with Closure Compiler renaming.
Use the `FormBuilder#group` overload with `AbstractControlOptions` instead.
so this is deprecated:
ingredientForm = this.fb.group({
ingredientType: ['', Validators.required],
ingredientFlavor: [''],
isMultiFlavor: [''],
ingredientBrand: [''],
ingredientName: [''],
imageFile: ['']
}, {validators: [ValidateThirdNumber.validate]});
and without the validators
option it's not.
my ValidateThirdNumber
validator:
class ValidateThirdNumber {
static validate(control: AbstractControl): void {
if (control) {
const isMultiFlavor = control.get('isMultiFlavor')?.value;
const ingredientFlavor = control.get('ingredientFlavor')?.value;
const ingredientBrand = control.get('ingredientBrand')?.value;
const ingredientName = control.get('ingredientName')?.value;
if (isMultiFlavor && ingredientFlavor.trim().length === 0) {
control.get('ingredientFlavor')?.setErrors({required_if: true});
} else {
control.get('ingredientFlavor')?.setErrors(null);
}
if (!ingredientFlavor && !ingredientBrand && !ingredientName) {
control.get('ingredientName')?.setErrors({required_at_least: true});
control.get('ingredientFlavor')?.setErrors({required_at_least: true});
control.get('ingredientBrand')?.setErrors({required_at_least: true});
} else {
control.get('ingredientName')?.setErrors(null);
control.get('ingredientFlavor')?.setErrors(null);
control.get('ingredientBrand')?.setErrors(null);
}
if (ingredientBrand && ingredientName && ingredientName === ingredientBrand) {
control.get('ingredientName')?.setErrors({not_the_same: true});
control.get('ingredientBrand')?.setErrors({not_the_same: true});
}
}
}
}
how do I overload it with AbstractControlOptions ?
回答1:
Problem description
From the documentation we see two different lines with the group()
function
group(controlsConfig: { [key: string]: any; }, options?: AbstractControlOptions): FormGroup
AND
group(controlsConfig: { [key: string]: any; }, options: { [key: string]: any; }): FormGroup
The difference in this lines is options?: AbstractControlOptions
and options: { [key: string]: any; }
To understand why angular is throwing this error we will now consider AbstractControlOptions
interface AbstractControlOptions {
validators?: ValidatorFn | ValidatorFn[] | null
asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null
updateOn?: 'change' | 'blur' | 'submit'
}
We continue to breakdown the problem by noting that the difference between this structure and your structure is ValidatorFn[]
interface ValidatorFn {
(control: AbstractControl): ValidationErrors | null
}
Overally, the error is thrown in your case because your Validator
function is expected to take a control and return ValidationErrors | null
. In the line validate(control: AbstractControl): void
, your code actually returns void
but expected to return a ValidationError | null
Solution
From the problem description, the solution is to simply modify the ValidatorFn
class ValidateThirdNumber {
static validate(control: AbstractControl): ValidationErrors | null {
if (control) {
const isMultiFlavor = control.get('isMultiFlavor')?.value;
const ingredientFlavor = control.get('ingredientFlavor')?.value;
const ingredientBrand = control.get('ingredientBrand')?.value;
const ingredientName = control.get('ingredientName')?.value;
if (isMultiFlavor && ingredientFlavor.trim().length === 0) {
control.get('ingredientFlavor')?.setErrors({required_if: true});
return ({required_if: true});
} else {
control.get('ingredientFlavor')?.setErrors(null);
}
if (!ingredientFlavor && !ingredientBrand && !ingredientName) {
control.get('ingredientName')?.setErrors({required_at_least: true});
control.get('ingredientFlavor')?.setErrors({required_at_least: true});
control.get('ingredientBrand')?.setErrors({required_at_least: true});
return ({required_at_least: true});
} else {
control.get('ingredientName')?.setErrors(null);
control.get('ingredientFlavor')?.setErrors(null);
control.get('ingredientBrand')?.setErrors(null);
}
if (ingredientBrand && ingredientName && ingredientName === ingredientBrand) {
control.get('ingredientName')?.setErrors({not_the_same: true});
control.get('ingredientBrand')?.setErrors({not_the_same: true});
return ({not_the_same: true});
}
}
return null;
}
}
来源:https://stackoverflow.com/questions/65155217/formbuilder-group-is-deprecated