Angular学习笔记50:响应式表单动态修改表单校验器

Angular学习笔记49:响应式表单验证(同步)之后,有时候会遇到这样的情况:

例如有三个属性:name,age,address,分别三个控件,有一个单选按钮,来控制用户输入哪一种输入属性。

创建一个分情况显示的表单

wujiayudeMacBook-Pro:demo-test wjy$ ng g c ModifyValidator
CREATE src/app/modify-validator/modify-validator.component.less (0 bytes)
CREATE src/app/modify-validator/modify-validator.component.html (35 bytes)
CREATE src/app/modify-validator/modify-validator.component.spec.ts (692 bytes)
CREATE src/app/modify-validator/modify-validator.component.ts (309 bytes)
UPDATE src/app/app.module.ts (2161 bytes)

修改app组件的模版文件

<app-modify-validator></app-modify-validator>

在modify-validator组件中创建一个分情况显示的表单
修改模版文件:

<nz-divider [nzText]="'动态修改响应式表单的校验器'"></nz-divider>
<form nz-form [formGroup]="validateForm">
  <nz-form-item>
    <nz-form-label nzSpan="4" nz-col>类别</nz-form-label>
    <nz-form-control nzSpan="12" nz-col>
      <nz-radio-group formControlName="category">
        <label nz-radio nzValue="name">name类别</label>
        <label nz-radio nzValue="age">age类别</label>
        <label nz-radio nzValue="address">地址类别</label>
      </nz-radio-group>
    </nz-form-control>
  </nz-form-item>
  <nz-form-item>
    <nz-form-label nzSpan="4" nz-col>name类别</nz-form-label>
    <nz-form-control nzSpan="12" nz-col>
      <input nz-input formControlName="name" name="name" placeholder="请输入name">
    </nz-form-control>
  </nz-form-item>

  <nz-form-item>
    <nz-form-label nzSpan="4" nz-col>age类别</nz-form-label>
    <nz-form-control nzSpan="12" nz-col>
      <input nz-input formControlName="age" name="age" placeholder="请输入age">
    </nz-form-control>
  </nz-form-item>

  <nz-form-item>
    <nz-form-label nzSpan="4" nz-col>地址类别</nz-form-label>
    <nz-form-control nzSpan="12" nz-col>
      <input nz-input formControlName="address" name="address" placeholder="请输入地址">
    </nz-form-control>
  </nz-form-item>

  <nz-form-item>
    <nz-form-label nzSpan="4" nz-col>表单是否有效</nz-form-label>
    <nz-form-control nzSpan="12" nz-col>
      {{validateForm.valid}}
    </nz-form-control>
  </nz-form-item>


</form>

修改类文件:

import {Component, OnInit} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';

@Component({
  selector: 'app-modify-validator',
  templateUrl: './modify-validator.component.html',
  styleUrls: ['./modify-validator.component.less']
})
export class ModifyValidatorComponent implements OnInit {
  public validateForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.validateForm = this.fb.group({
      category: [null, [Validators.required]],
      name: [null, [Validators.required]],
      age: [null, [Validators.required]],
      address: [null, [Validators.required]],
    });
  }

  ngOnInit() {
  }

}

保存,页面如下:

在这里插入图片描述

此时name,age,address这三个属性都是有必须填的校验器。而此时要做的就是在用户点击类别的时候,点击哪一个,哪一个必填,其他的就不用必填了。

为“类别”的单选控件增加一个检测事件。

// 通过category选中的选项分别进行处理
public handleCategoryChange(category: string): void {
    switch (category) {
      case 'name':
        this.validateForm.get('name').setValidators([Validators.required]);
        this.validateForm.get('age').clearValidators();
        this.validateForm.get('address').clearValidators();
        break;
      case 'age':
        this.validateForm.get('name').clearValidators();
        this.validateForm.get('age').setValidators([Validators.required]);
        this.validateForm.get('address').clearValidators();
        break;
      case 'address':
        this.validateForm.get('name').clearValidators();
        this.validateForm.get('age').clearValidators();
        this.validateForm.get('address').setValidators([Validators.required]);
        break;
      default:
        break;
    }
    this.validateForm.updateValueAndValidity();
  }

并在constructor中增加validateForm的状态变更的订阅事件。

constructor(private fb: FormBuilder) {
    this.validateForm = this.fb.group({
      category: [null, [Validators.required]],
      name: [null, [Validators.required]],
      age: [null, [Validators.required]],
      address: [null, [Validators.required]],
    });
    this.validateForm.statusChanges.subscribe(status => {
      console.log(status);
      console.log(this.validateForm);
    });
  }

保存,选择name,然后在name属性中输入以后,这个表单就是有效了。但是实际情况,表单的状态并不是有效。

在这里插入图片描述

分析原因发现,表单中的age、address实例的状态是"INVALID"(无效的),但是看到age,adddress这两个实例的校验器已经清除了。但是表单的状态却没有更新。

在这里插入图片描述

解决方案1: 单独更新每一个实例

修改handleCategoryChange()方法

public handleCategoryChange(category: string): void {
    switch (category) {
      case 'name':
        this.validateForm.get('name').setValidators([Validators.required]);
        this.validateForm.get('age').clearValidators();
        this.validateForm.get('address').clearValidators();
        break;
      case 'age':
        this.validateForm.get('name').clearValidators();
        this.validateForm.get('age').setValidators([Validators.required]);
        this.validateForm.get('address').clearValidators();
        break;
      case 'address':
        this.validateForm.get('name').clearValidators();
        this.validateForm.get('age').clearValidators();
        this.validateForm.get('address').setValidators([Validators.required]);
        break;
      default:
        break;
    }
    this.validateForm.get('name').updateValueAndValidity();
    this.validateForm.get('age').updateValueAndValidity();
    this.validateForm.get('address').updateValueAndValidity();
  }

保存以后,发现解决了上述问题。

在这里插入图片描述

此时,在选择了name以后,其他的两个实例已经进行了更新,并在表单中更新了状态。

解决方案1: 更新所有实例,刷新状态

修改handleCategoryChange()方法

public handleCategoryChange(category: string): void {
    switch (category) {
      case 'name':
        this.validateForm.get('name').setValidators([Validators.required]);
        this.validateForm.get('age').clearValidators();
        this.validateForm.get('address').clearValidators();
        break;
      case 'age':
        this.validateForm.get('name').clearValidators();
        this.validateForm.get('age').setValidators([Validators.required]);
        this.validateForm.get('address').clearValidators();
        break;
      case 'address':
        this.validateForm.get('name').clearValidators();
        this.validateForm.get('age').clearValidators();
        this.validateForm.get('address').setValidators([Validators.required]);
        break;
      default:
        break;
    }
    this.validateForm.updateValueAndValidity();
    this.validateForm.enable();
  }

更新了表单中的实例校验器以后,然后通过enable()方法,根据值和校验器重新计算状态。从而达到了更新状态的目的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值