angular 具有多个同步验证器的表单是有效的,尽管它应该是无效的
angular forms with multiple sync validators are valid despite it should be invalid
我有 2 个 FormControl。
当其中一个控件的值比另一个控件的值 greater/small 时,我在 html 中得到了正确的错误验证,并且 form.valid 为真。
this.bestGradeScoresFormControl.setValidators(bestScoresGreaterThanWorstScoresValidator(this.worstGradeScoresFormControl),
Validators.max(100)]);
this.worstGradeScoresFormControl.setValidators(worstScoresSmallerThanBestScoresValidator(this.bestGradeScoresFormControl));
然后我使用 Compose 函数将 Validators.max(100) 添加到 bestScores 控件中:
this.bestGradeScoresFormControl.setValidators(Validators.compose(
[bestScoresGreaterThanWorstScoresValidator(this.worstGradeScoresFormControl), Validators.max(100)]));
this.worstGradeScoresFormControl.setValidators(worstScoresSmallerThanBestScoresValidator(this.bestGradeScoresFormControl));
当我为最佳分数控制设置 101 个分数时,我得到:'More than 100 scores are not allowed' 并且 form.valid 为 FALSE,这是正确的!
但是...
当我现在将最差分数控制值更改为有效值时,之前的 'max error' 突然消失并且 form.valid 为真,那是不正确的!
我没有使用 Compose 方法,而是尝试使用验证器数组,例如:
this.bestGradeScoresFormControl.setValidators([bestScoresGreaterThanWorstScoresValidator(this.worstGradeScoresFormControl), Validators.max(100)]);
this.worstGradeScoresFormControl.setValidators(worstScoresSmallerThanBestScoresValidator(this.bestGradeScoresFormControl));
行为相同???
这里有什么问题?为什么将 worstScore 控制值 form.valid 值从 FALSE 更改为 TRUE?
export const bestScoresGreaterThanWorstScoresValidator = (worstScoreControl: FormControl): ValidatorFn => {
return (control: FormControl): { [key: string]: boolean } => {
if (control.value > worstScoreControl.value) {
worstScoreControl.setErrors(null);
control.setErrors(null);
}
else {
worstScoreControl.setErrors({ "bestScoresGreaterThanWorstScores": true });
return { 'bestScoresGreaterThanWorstScores': true };
}
};
}
export const worstScoresSmallerThanBestScoresValidator = (bestScoreControl: FormControl): ValidatorFn => {
return (control: FormControl): { [key: string]: boolean } => {
if (control.value < bestScoreControl.value) {
bestScoreControl.setErrors(null);
control.setErrors(null);
}
else {
bestScoreControl.setErrors({ "worstScoresSmallerThanBestScores": true });
return { 'worstScoresSmallerThanBestScores': true };
}
};
}
更新
我在这里放了一个plunkr来说明问题:
https://plnkr.co/edit/ygiVNtPImkMveLGogTk2?p=preview
在我看来,解决方案不能是我在整个表单上创建一个唯一的自定义验证器,因为我希望所有自定义验证器都有自己的验证器 class/function。
如果您根据我的 plunkr 代码做出解决方案,那么赏金就是您的:-)
尽管没有 add/remove 针对 angular 表单控件错误的特定错误这样的功能,但您可以自己实现它。
function addError(control: AbstractControl, errorKey: string) {
const errors = control.errors || {};
errors[errorKey] = true;
control.setErrors(errors);
}
function removeError(control: AbstractControl, errorKey: string) {
const errors = control.errors || {};
delete errors[errorKey];
control.setErrors(Object.keys(errors).length ? errors : null)
}
现在只需在自定义验证器中需要时添加或删除错误即可:
bestScoresGreaterThanWorstScoresValidator
export const bestScoresGreaterThanWorstScoresValidator =
(worstScoreControl: FormControl): ValidatorFn => {
return (control: FormControl): { [key: string]: boolean } => {
if (control.value > worstScoreControl.value) {
removeError(worstScoreControl, 'worstScoresSmallerThanBestScores')
return null;
}
else {
addError(worstScoreControl, 'worstScoresSmallerThanBestScores');
return { 'bestScoresGreaterThanWorstScores': true };
}
};
}
worstScoresSmallerThanBestScoresValidator
export const worstScoresSmallerThanBestScoresValidator =
(bestScoreControl: FormControl): ValidatorFn => {
return (control: FormControl): { [key: string]: boolean } => {
if (control.value < bestScoreControl.value) {
removeError(bestScoreControl, 'bestScoresGreaterThanWorstScores')
return null;
}
else {
addError(bestScoreControl, 'bestScoresGreaterThanWorstScores');
return { 'worstScoresSmallerThanBestScores': true };
}
};
}
我有 2 个 FormControl。
当其中一个控件的值比另一个控件的值 greater/small 时,我在 html 中得到了正确的错误验证,并且 form.valid 为真。
this.bestGradeScoresFormControl.setValidators(bestScoresGreaterThanWorstScoresValidator(this.worstGradeScoresFormControl),
Validators.max(100)]);
this.worstGradeScoresFormControl.setValidators(worstScoresSmallerThanBestScoresValidator(this.bestGradeScoresFormControl));
然后我使用 Compose 函数将 Validators.max(100) 添加到 bestScores 控件中:
this.bestGradeScoresFormControl.setValidators(Validators.compose(
[bestScoresGreaterThanWorstScoresValidator(this.worstGradeScoresFormControl), Validators.max(100)]));
this.worstGradeScoresFormControl.setValidators(worstScoresSmallerThanBestScoresValidator(this.bestGradeScoresFormControl));
当我为最佳分数控制设置 101 个分数时,我得到:'More than 100 scores are not allowed' 并且 form.valid 为 FALSE,这是正确的!
但是...
当我现在将最差分数控制值更改为有效值时,之前的 'max error' 突然消失并且 form.valid 为真,那是不正确的!
我没有使用 Compose 方法,而是尝试使用验证器数组,例如:
this.bestGradeScoresFormControl.setValidators([bestScoresGreaterThanWorstScoresValidator(this.worstGradeScoresFormControl), Validators.max(100)]);
this.worstGradeScoresFormControl.setValidators(worstScoresSmallerThanBestScoresValidator(this.bestGradeScoresFormControl));
行为相同???
这里有什么问题?为什么将 worstScore 控制值 form.valid 值从 FALSE 更改为 TRUE?
export const bestScoresGreaterThanWorstScoresValidator = (worstScoreControl: FormControl): ValidatorFn => {
return (control: FormControl): { [key: string]: boolean } => {
if (control.value > worstScoreControl.value) {
worstScoreControl.setErrors(null);
control.setErrors(null);
}
else {
worstScoreControl.setErrors({ "bestScoresGreaterThanWorstScores": true });
return { 'bestScoresGreaterThanWorstScores': true };
}
};
}
export const worstScoresSmallerThanBestScoresValidator = (bestScoreControl: FormControl): ValidatorFn => {
return (control: FormControl): { [key: string]: boolean } => {
if (control.value < bestScoreControl.value) {
bestScoreControl.setErrors(null);
control.setErrors(null);
}
else {
bestScoreControl.setErrors({ "worstScoresSmallerThanBestScores": true });
return { 'worstScoresSmallerThanBestScores': true };
}
};
}
更新
我在这里放了一个plunkr来说明问题:
https://plnkr.co/edit/ygiVNtPImkMveLGogTk2?p=preview
在我看来,解决方案不能是我在整个表单上创建一个唯一的自定义验证器,因为我希望所有自定义验证器都有自己的验证器 class/function。
如果您根据我的 plunkr 代码做出解决方案,那么赏金就是您的:-)
尽管没有 add/remove 针对 angular 表单控件错误的特定错误这样的功能,但您可以自己实现它。
function addError(control: AbstractControl, errorKey: string) {
const errors = control.errors || {};
errors[errorKey] = true;
control.setErrors(errors);
}
function removeError(control: AbstractControl, errorKey: string) {
const errors = control.errors || {};
delete errors[errorKey];
control.setErrors(Object.keys(errors).length ? errors : null)
}
现在只需在自定义验证器中需要时添加或删除错误即可:
bestScoresGreaterThanWorstScoresValidator
export const bestScoresGreaterThanWorstScoresValidator =
(worstScoreControl: FormControl): ValidatorFn => {
return (control: FormControl): { [key: string]: boolean } => {
if (control.value > worstScoreControl.value) {
removeError(worstScoreControl, 'worstScoresSmallerThanBestScores')
return null;
}
else {
addError(worstScoreControl, 'worstScoresSmallerThanBestScores');
return { 'bestScoresGreaterThanWorstScores': true };
}
};
}
worstScoresSmallerThanBestScoresValidator
export const worstScoresSmallerThanBestScoresValidator =
(bestScoreControl: FormControl): ValidatorFn => {
return (control: FormControl): { [key: string]: boolean } => {
if (control.value < bestScoreControl.value) {
removeError(bestScoreControl, 'bestScoresGreaterThanWorstScores')
return null;
}
else {
addError(bestScoreControl, 'bestScoresGreaterThanWorstScores');
return { 'worstScoresSmallerThanBestScores': true };
}
};
}