如何根据 Angular 11 中 html 代码处的条件使反应式表单字段成为必填字段
How to make reactive form fields mandatory based on condition at html code in Angular 11
我的表单中有两个 select/dropdown 字段,第二个下拉字段根据条件 *ngIf="selectedStdntList?.packages"
呈现。但是在下面的代码中,它会停止提交表单,即使条件 *ngIf="selectedStdntList?.packages"
不成立并且第二个下拉菜单没有呈现在屏幕上。
学生-list.component.html
<form [formGroup]="moveStudentForm" #formDirective="ngForm" (ngSubmit)="moveStudent();">
<uitk-form-field>
<label uitkLabel>Student List:</label>
<uitk-select id="my-required-reactive-select" formControlName="stdntListCtrl"
[itemList]="stdntListDropdown" [showError]="moveStudentForm?.controls?.stdntListCtrl?.errors?.required"
defaultLabel="Please Select" defaultLabelFlag="true">
</uitk-select>
<uitk-form-field-error
*ngIf="moveStudentForm?.controls?.stdntListCtrl?.errors?.required && moveStudentForm?.controls?.stdntListCtrl?.touched">
<span>Please select student list</span>
</uitk-form-field-error>
</uitk-form-field>
<uitk-form-field *ngIf="selectedStdntList?.packages">
<label uitkLabel>Package:</label>
<uitk-select id="my-required-reactive-select" formControlName="moveStudentPackageCtrl" [itemList]="packagesDropdown"
[showError]="moveStudentForm?.controls?.packageCtrl?.errors?.required" defaultLabel="Please Select"
defaultLabelFlag="true">
</uitk-select>
<uitk-form-field-error
*ngIf="moveStudentForm?.controls?.packageCtrl?.errors?.required && moveStudentForm?.controls?.packageCtrl?.touched">
<span>Please select package</span>
</uitk-form-field-error>
</uitk-form-field>
</form>
学生-list.component.ts
@Component({
selector: 'stdnt-list',
templateUrl: './stdnt-list.component.html',
styleUrls: ['./stdnt-list.component.scss']
})
export class StdntListComponent implements OnInit {
stdntListDropdown: IUITKSelectItemProps[] = [];
moveStudentForm: FormGroup;
constructor(private dataService: DataService)
this.moveStudentForm = new FormGroup({
stdntListCtrl: new FormControl(null, Validators.required),
moveStudentPackageCtrl: new FormControl(null, Validators.required),
});
}
ngOnInit() {
this.stdntList = this.dataService.loadStudentData();
}
moveStudent() {
...
}
}
期望输出:
如果第二个字段条件 *ngIf="selectedStdntList?.packages"
为真,那么只有该字段的验证器应该工作,否则只有第一个字段验证器应该工作并且应该允许提交表单。
要使 formControl“不验证”,您有两个选择:创建自定义验证器或禁用 FormControl
创建自定义验证器类型“requiredIf”。创建自定义验证器有一个问题,即在条件更改时需要 UpdateValueAndValiddity FormControl。在 中,它使用垫输入的事件(更改)。我不知道你的“uitk-select”是否有事件(变化)或类似的(*)
要在正常输入中禁用 formControl,您不能使用 [disabled],否则您需要使用指令(例如 ), or, again, if your "uitk-select" has an [disable] property or you can use the event (change) to disabled the formControl -using the methods enable and disabled-。但在这种情况下 重要 你需要使用
[style.display]="!selectedStdntList?.packages?'none':null"
不是 *ngIf
(*)当您使用非标准库时,请注明您使用的库帮助我们帮助您。
您可以根据 selectedStdntList
值动态设置验证器。
this.moveStudentForm = new FormGroup({
stdntListCtrl: new FormControl(null, Validators.required),
moveStudentPackageCtrl: new FormControl(null)
});
// Need to add/clear validator based on selectedStdntList?.packages value dynamically
// Not sure how are you using 'selectedStdntList' in StdntListComponent
// Below code should be executed whenever 'selectedStdntList' value changes
const moveStudentPackageCtrl = this.moveStudentForm.get('moveStudentPackageCtrl');
if (this.selectedStdntList?.packages) {
// set validators - PS: this will clear previous Validators if any, and only set the ones specified here
moveStudentPackageCtrl?.setValidators(Validators.required);
} else {
// clear validator
moveStudentPackageCtrl?.clearValidators();
}
moveStudentPackageCtrl?.updateValueAndValidity();
作为替代设置和清除验证器的替代方法,您甚至可以动态添加或删除表单控件moveStudentPackageCtrl
:
this.moveStudentForm = new FormGroup({
stdntListCtrl: new FormControl(null, Validators.required)
});
// Add/remove control based on selectedStdntList?.packages value dynamically
// Not sure how are you using 'selectedStdntList' in StdntListComponent
// Below code should be executed whenever 'selectedStdntList' value changes
if (this.selectedStdntList?.packages) {
this.moveStudentForm.addControl('moveStudentPackageCtrl', new FormControl(null, Validators.required));
} else {
this.moveStudentForm.removeControl('moveStudentPackageCtrl');
}
我的表单中有两个 select/dropdown 字段,第二个下拉字段根据条件 *ngIf="selectedStdntList?.packages"
呈现。但是在下面的代码中,它会停止提交表单,即使条件 *ngIf="selectedStdntList?.packages"
不成立并且第二个下拉菜单没有呈现在屏幕上。
学生-list.component.html
<form [formGroup]="moveStudentForm" #formDirective="ngForm" (ngSubmit)="moveStudent();">
<uitk-form-field>
<label uitkLabel>Student List:</label>
<uitk-select id="my-required-reactive-select" formControlName="stdntListCtrl"
[itemList]="stdntListDropdown" [showError]="moveStudentForm?.controls?.stdntListCtrl?.errors?.required"
defaultLabel="Please Select" defaultLabelFlag="true">
</uitk-select>
<uitk-form-field-error
*ngIf="moveStudentForm?.controls?.stdntListCtrl?.errors?.required && moveStudentForm?.controls?.stdntListCtrl?.touched">
<span>Please select student list</span>
</uitk-form-field-error>
</uitk-form-field>
<uitk-form-field *ngIf="selectedStdntList?.packages">
<label uitkLabel>Package:</label>
<uitk-select id="my-required-reactive-select" formControlName="moveStudentPackageCtrl" [itemList]="packagesDropdown"
[showError]="moveStudentForm?.controls?.packageCtrl?.errors?.required" defaultLabel="Please Select"
defaultLabelFlag="true">
</uitk-select>
<uitk-form-field-error
*ngIf="moveStudentForm?.controls?.packageCtrl?.errors?.required && moveStudentForm?.controls?.packageCtrl?.touched">
<span>Please select package</span>
</uitk-form-field-error>
</uitk-form-field>
</form>
学生-list.component.ts
@Component({
selector: 'stdnt-list',
templateUrl: './stdnt-list.component.html',
styleUrls: ['./stdnt-list.component.scss']
})
export class StdntListComponent implements OnInit {
stdntListDropdown: IUITKSelectItemProps[] = [];
moveStudentForm: FormGroup;
constructor(private dataService: DataService)
this.moveStudentForm = new FormGroup({
stdntListCtrl: new FormControl(null, Validators.required),
moveStudentPackageCtrl: new FormControl(null, Validators.required),
});
}
ngOnInit() {
this.stdntList = this.dataService.loadStudentData();
}
moveStudent() {
...
}
}
期望输出:
如果第二个字段条件 *ngIf="selectedStdntList?.packages"
为真,那么只有该字段的验证器应该工作,否则只有第一个字段验证器应该工作并且应该允许提交表单。
要使 formControl“不验证”,您有两个选择:创建自定义验证器或禁用 FormControl
创建自定义验证器类型“requiredIf”。创建自定义验证器有一个问题,即在条件更改时需要 UpdateValueAndValiddity FormControl。在
要在正常输入中禁用 formControl,您不能使用 [disabled],否则您需要使用指令(例如
[style.display]="!selectedStdntList?.packages?'none':null"
不是 *ngIf
(*)当您使用非标准库时,请注明您使用的库帮助我们帮助您。
您可以根据 selectedStdntList
值动态设置验证器。
this.moveStudentForm = new FormGroup({
stdntListCtrl: new FormControl(null, Validators.required),
moveStudentPackageCtrl: new FormControl(null)
});
// Need to add/clear validator based on selectedStdntList?.packages value dynamically
// Not sure how are you using 'selectedStdntList' in StdntListComponent
// Below code should be executed whenever 'selectedStdntList' value changes
const moveStudentPackageCtrl = this.moveStudentForm.get('moveStudentPackageCtrl');
if (this.selectedStdntList?.packages) {
// set validators - PS: this will clear previous Validators if any, and only set the ones specified here
moveStudentPackageCtrl?.setValidators(Validators.required);
} else {
// clear validator
moveStudentPackageCtrl?.clearValidators();
}
moveStudentPackageCtrl?.updateValueAndValidity();
作为替代设置和清除验证器的替代方法,您甚至可以动态添加或删除表单控件moveStudentPackageCtrl
:
this.moveStudentForm = new FormGroup({
stdntListCtrl: new FormControl(null, Validators.required)
});
// Add/remove control based on selectedStdntList?.packages value dynamically
// Not sure how are you using 'selectedStdntList' in StdntListComponent
// Below code should be executed whenever 'selectedStdntList' value changes
if (this.selectedStdntList?.packages) {
this.moveStudentForm.addControl('moveStudentPackageCtrl', new FormControl(null, Validators.required));
} else {
this.moveStudentForm.removeControl('moveStudentPackageCtrl');
}