当nz-checkbox-group多选框组遇上必选校验
当nz-checkbox-group多选框组遇上必选校验
Angular2 ng-zorro-antd checkbox
今天表单中用到ng-zorro-antd组件的多选框nz-checkbox-group,最开始用的是响应式表单的验证+响应式表单的验证,结果总是无法达到预期效果。
本篇是讲述的是从遇到问题到最终解决问题的全过程,对于想要直接获取答案的小伙伴可直接跳至 再次尝试 一节。
初始代码及问题现象:
问题.Html
<div nz-form-item nz-row>
<div nz-form-label nz-col [nzSpan]="4">
<label for="one" nz-form-item-required>复选测试</label>
</div>
<div nz-form-control nz-col [nzSpan]="10" [nzValidateStatus]="getFormControl('one')">
<nz-checkbox-group formControlName="one" [(ngModel)]="oneOption" ></nz-checkbox-group>
<div nz-form-explain *ngIf="getFormControl('one').dirty&&getFormControl('one').hasError('required')">通知范围必选</div>
</div>
</div>
2
3
4
5
6
7
8
9
问题.ts 这里仅列出关键代码部分
validateForm: FormGroup;
oneOption: any;
constructor(
private fb: FormBuilder,
){}
ngOnInit() {
this.oneOption = [
{ label: 'Apple', value: 'Apple', checked: true },
{ label: 'Pear', value: 'Pear', checked: false },
{ label: 'Orange', value: 'Orange', checked: false },
]
this.validateForm = this.fb.group({
one: [null, [Validators.required]],
})
}
getFormControl(name) {
return this.validateForm.controls[name];
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
为了找问题,在提交方法_submitForm()中添加了几个打印
console.log(this.getFormControl('one').dirty); // 1
console.log(this.getFormControl('one').hasError('required')); // 2
console.log(this.validateForm.value.one); // 3
console.long(this.validateForm.invalid);// 4
2
3
4
结果发现
- 初始时:1、false,2、false,3、oneOption中的值,4、false
- 选择一个选项后:1、true,2、false,3、oneOption中的值+选中的value,4、false
从而始终无法触发显示 “通知范围必选”
第一次尝试
最开始尝试是将this.validateForm.value.scopes
在提交时先赋值为[],再检测checked状态,赋值。
this.validateForm.value.scopes = [];
for(const i in this.oneOption){
if(this.oneOption[i].checked){
this.validateForm.value.scopes.push(this.oneOption[i].value);
}
}
2
3
4
5
6
这样写 ,this.validateForm.value.one
是达到预期了,但提示效果依旧没出来。 继续探索,看到getFormControl('one').hasError('required')
,既然有has,有没有set一类的?打了一下发现还真有一个this.getFormControl(‘one’).setErrors()的方法,于是在上面的基础上想到这样一个方式:
if(this.validateForm.value.scopes.length == 0){
this.getFormControl('one').setErrors(Validators.required);
}
2
3
发现一点用没有,搜索后找到另一种变形:
if(this.validateForm.value.scopes.length == 0){
this.getFormControl('one').setErrors({'required':true});
}
2
3
发现上面的2可以变成true了,但1始终是false,导致无效。
再次尝试
到这曾一度想过放弃然后自己用原始方式写,再一想到原始方式还要自己考虑样式什么的,作为一个有着css恐惧症的Java程序猿我决然地选择了硬着头皮在啃会儿。
在刷了n+1遍ng-zorro-antd的官方文档的表单部分后,在“自定义异步校验”中看到这样一句话 :
当使用 响应式表单(Reactive Form) 时,<nz-form-control> 的 nzValidateStatus 会自动从 NgControl 中获取数据,也可以手动指定特定的 NgControl组件将表单校>验函数的校验过程和异步返回的结果显示对应的error | validating(pending) | warning | success状态,具体使用方式建议参照本demo ----- NG-ZORRO表单一节的文档
本着死马当活马医的心点开里面的dome,仔细看了下,同时在实例上试了一下,发现这不正是梦寐以求的咩。于是有了如下的终极解决方案:
问题.html中不用做修改。
问题.ts修改如下:
//因为不想在提交方法_submitForm()再循环一遍获取多选结果,就只好在这先定义一个临时的用于存储选择结果。
selectedOne: any = [];
validateForm: FormGroup;
oneOption: any;
constructor(
private fb: FormBuilder,
){}
ngOnInit() {
this.oneOption = [
{ label: 'Apple', value: 'Apple', checked: true },
{ label: 'Pear', value: 'Pear', checked: false },
{ label: 'Orange', value: 'Orange', checked: false },
]
this.validateForm = this.fb.group({
one: [null, [this.onesValidator]],//修改校验规则为下面自定义的onesValidator
})
}
getFormControl(name) {
return this.validateForm.controls[name];
}
_submitForm() {
this.validateForm.value.one = this.selectedOne;
}
//创建自定义校验规则onesValidator,用于复选框组校验时调用。
onesValidator= (control: FormControl): { [s: string]: boolean } => {
this.selectedOne = [];
for (const i in control.value) {
if (control.value[i].checked) {
this.selectedOne.push(control.value[i]);
}
}
if (this.selectedOne.length == 0) {
return { required: true};
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
改完后测试,nice, 一切走上正轨。至此圆满结束,完结撒花~
除特别注明外,本站所有文章均为 Windcoder网 原创,转载请注明出处来自: dangnz-checkbox-groupduoxuankuangzuyushangbixuanxiaoyan

No Data