我有一个下拉菜单,根据所选选项,我显示特定的表单控件。对于下拉选项value2,我显示了一条错误消息:“请提供正文或用户名和密码”,表示需要其中一个字段才能保存表单。问题是,当我从下拉列表中选择选项value1或value3时,错误消息(h6)仍会出现在表单上,atLeastOne验证错误仍然存在。即使更改了下拉列表值,我也无法重置或清除此错误。
模板代码:
<form [formGroup]="form">
<h2 style="display: inline-block;">{{action}} {{operationName}}</h2>
<h6 style="color: red; display: inline-block;margin: 0;margin-left: 0.3rem;"
*ngIf="isSaveDisabled()">
(Required Field is/are missing)
</h6>
<h6 style="color: red; display: inline-block;margin: 0;margin-left: 0.3rem;"
*ngIf="form.getError('atLeastOne') != null">
(Please provide either the Auth Request Body or both Username and Password)
</h6>
<ng-container [ngSwitch]="column['type']">
<select *ngSwitchCase="'dropdown'" id="{{column['label']}}"
formControlName="{{column['label']}}"
(change)="handleDropdownChange(column['label'])">
<option value="">ALL</option>
<option *ngFor="let item of column['options']" [value]="item">
{{item}}
</option>
</select>
</ng-container>
</form>
ts文件:-
ngOnInit() {
this.columns = [
{
label: 'Type',
value: '',
type: 'dropdown',
required: true,
options: ['value1', 'value2', 'value3'],
},
{
label: 'Body',
value: '',
type: 'inputTextArea',
required: true,
},
{
label: 'Username',
value: '',
type: 'inputTextField',
required: true,
},
{
label: 'Password',
value: '',
type: 'inputTextField',
required: true,
},
];
this.columns?.forEach((column) => {
const control = this.fb.control(
column.value,
column.required ? Validators.required : null
);
this.form.addControl(column.label, control);
});
if (value === 'value2') {
console.log('this is called');
this.form.get('Username')!.clearValidators();
this.form.get('Password')!.clearValidators();
this.form.get('Body')!.clearValidators();
this.form.setValidators(this.conditionalValidator());
this.form.updateValueAndValidity();
this.cdr.detectChanges();
}
console.log('Form after adding controls: ', this.form.value);
}
}
handleDropdownChange(value: string): void {
console.log('Handling Option2 change:', value);
console.log('Before:', JSON.stringify(this.form.errors, null, 2));
console.log('1 ' + this.form.getError('required'));
Object.keys(this.form.controls).forEach((key) => {
const control = this.form.get(key);
console.log('Control error:', control?.errors);
if (control) {
control.setErrors(null);
control.updateValueAndValidity();
}
});
console.log('2 ' + this.form.getError('required'));
console.log('1 ' + this.form.getError('atLeastOne'));
this.form.setErrors({ atLeastOne: 'good' });
this.form.updateValueAndValidity();
console.log('2 ' + this.form.getError('atLeastOne'));
this.form.get('atLeastOne')?.setErrors({
atLeastOne: 'Atasdsd.',
});
this.form.updateValueAndValidity();
this.cdr.detectChanges();
this.clearRequiredValidators();
console.log('Form errors after:', JSON.stringify(this.form.errors, null, 2));
this.populateForm(value);
}
conditionalValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const body = control.get('Body');
const username = control.get('Username');
const password = control.get('Password');
if (body && authRequestBody.value.length > 0) {
return null;
}
if (
username &&
password &&
username.value.length > 0 &&
password.value.length > 0
) {
return null;
}
return { atLeastOne: 'At least one field has to be provided.' };
};
}
控制台打印:-
Before: {
"atLeastOne": "At least one field has to be provided."
}
consumer-details.component.ts:418 1 undefined
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: {required: true}
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:432 2 undefined
consumer-details.component.ts:434 1 At least one field has to be provided.
consumer-details.component.ts:437 2 At least one field has to be provided.
consumer-details.component.ts:446 Form errors afte: {
"atLeastOne": "At least one field has to be provided."
}
即使在更改下拉值后,h6消息也会显示出来。我正在使用自定义验证器功能