当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>

问题.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];
}

为了找问题,在提交方法_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

结果发现

  • 初始时: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);
	}
}

这样写 ,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);
}

发现一点用没有,搜索后找到另一种变形:

if(this.validateForm.value.scopes.length == 0){
	this.getFormControl('one').setErrors({'required':true});
}

发现上面的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};
    }
};

改完后测试,nice, 一切走上正轨。至此圆满结束,完结撒花~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据科学与人工智能

【Python环境】Python爬虫入门(2):爬虫基础了解

1.什么是爬虫 爬虫,即网络爬虫,大家可以理解为在网络上爬行的一直蜘蛛,互联网就比作一张大网,而爬虫便是在这张网上爬来爬去的蜘蛛咯,如果它遇到资源,那么它就会抓...

28390
来自专栏数据和云

DBA生存警示:误关闭生产库案例及防范建议

编辑手记:对于资深的老DBA们,他们在漫长的职业生涯中养成了很多稀奇古怪的守则,以在复杂多变的环境中“幸存”,这源于无数血泪的教训,我曾经在《数据安全警示录》...

35070
来自专栏逸鹏说道

大公司都有哪些开源项目之腾讯

1.WeUI 为微信Web服务量身设计 WeUI 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信 Web 开发量身设计,可以令用户的使用感知...

51860
来自专栏菩提树下的杨过

mac OS X Yosemite 上编译hadoop 2.6.0/2.7.0及TEZ 0.5.2/0.7.0 注意事项

1、jdk 1.7问题 hadoop 2.7.0必须要求jdk 1.7.0,而oracle官网已经声明,jdk 1.7 以后不准备再提供更新了,所以趁现在还能下...

21080
来自专栏菩提树下的杨过

monoTouch开发(1):win7 + vmware下安装mac os

iPhone现在越来越火爆了,很多原本在PC上的互联网应用都纷纷推出了iPhone客户端(比如携程,新浪微博),iPhone的最佳开发环境是mac OS + i...

22860
来自专栏实用工具入门教程

如何部署 NTP 服务器

NTP 全称为 Network Time Protocol ,中文翻译为网络时间协议,1985年就已经被提出,旨在缩短互联网上所有计算机设备与 UTC 的时间差...

55910
来自专栏开源项目

2017 JavaScript 开发者的学习图谱 | 码云周刊第 25 期

码云项目推荐 1前端框架类 1. 基于 Vue.js 的 UI 组件库 iView ? 项目简介:iView 是一套基于 Vue.js 的 UI 组件库,主要服...

35970
来自专栏漏斗社区

skr ~~HID攻击之实战篇

在之前的关于HID攻击介绍文章中,学习了解了HID攻击,是否感觉很有趣呢?是否也想在实际中进行操作一波呢?接下来,就跟着斗哥进行实践玩耍吧:通过Badusb高效...

9110
来自专栏张戈的专栏

SEO养博客神器:同步文章(或摘要)到新浪博客的WordPress插件

了解 SEO 的站长都会另外用心做几个博客,起到 SEO 辅助作用。通常说的养博客主要是养 BSP 博客。比如新浪博客,网易博客,百度空间,网易博客,新浪博客,...

45460
来自专栏落影的专栏

iOS近距离实时通信解决方案

前言 最近研究iOS设备间的近距离实时通信,对其解决方案进行了解,整理如下: ? 其中AirDrop常用于iOS/OS X系统间分享图片、视频等,但实...

39340

扫码关注云+社区

领取腾讯云代金券