Angular响应式表单校验及提交主动触发所有校验

images

一、使用响应式表单的步骤

1、在模块(一般是app.module.ts)中引入ReactiveFormsModule

2、在组件的ts文件中使用响应式表单

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
@Component({
    selector: 'app-form-validate',
    templateUrl: './form-validate.page.html',
    styleUrls: ['./form-validate.page.scss'],
})
export class FormValidatePage implements OnInit {
    public myForm: FormGroup;
    
    constructor(private fb: FormBuilder) {
        this.createForm();
    }
    
    ngOnInit() {
    }
    
    // 创建表单元素
    createForm() {
        this.myForm = this.fb.group({
            username: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(6)]],
            mobile: ['', [Validators.required]],
            password: this.fb.group({
                        pass1: [''],
                        pass2: ['']
                        })
        });
    }
    
    // 提交表单函数
    postDate() {
        /**
         * valid:是否有效
         * invalid:无效
         * dirty:脏
         * status:状态
         * errors:显示错误
         */
        if(this.myForm.valid){
            console.log(this.myForm.value);
        }
        else
        {
            //如果验证失败:主动循环触发验证错误信息显示在界面上
            for (const i in this.myForm.controls) {
            this.myForm.controls[i].markAsTouched();
            this.myForm.controls[i].updateValueAndValidity();
        }
        
     }
    
    }

}

3、在组件的html页面中使用

<form [formGroup]="myForm" (ngSubmit)="postDate()">
    <div class="form-group">
        <label for="username">用户名:</label>
        <input type="text" placeholder="请输入用户名" [class.error]="myForm.get('username').invalid && myForm.get('username').touched"
        class="form-control" id="username" formControlName="username" />
        <!-- 当输入框没有访问的时候或者合法的时候不显示 -->
        <div [hidden]="myForm.get('username').valid || myForm.get('username').untouched">
            <p [hidden]="!myForm.hasError('required','username')">用户名必填的</p>
            <p [hidden]="!myForm.hasError('minlength','username')">用户名长度过短</p>
            <p [hidden]="!myForm.hasError('maxlength','username')">用户名长度太长</p>
        </div>
    </div>
    <div class="form-group">          
        <label for="mobile">手机号码:</label>          
        <input type="text" placeholder="请输入手机号码" class="form-control" id="mobile" formControlName="mobile"/>          
        <div [hidden]="myForm.get('mobile').valid || myForm.get('mobile').untouched">          
        <p [hidden]="!myForm.hasError('mobile', 'mobile')">{{myForm.getError('mobile', 'mobile')?.info}}</p>          
    </div>          
    </div>          
    <div formGroupName="password" style="border:none;">          
        <p class="form-group">          
        <label>密码:</label>          
        <input type="password" class="form-control" placeholder="请输入密码" formControlName="pass1" />          
        </p>          
        <p class="form-group">          
        <label>确认密码:</label>          
        <input type="password" class="form-control" placeholder="请再次输入密码" formControlName="pass2" />          
        </p>
        <!-- 对于group可以不在外面加一层判断 -->
        <div>          
            <p [hidden]="!myForm.hasError('passValidator','password')">          
            {{myForm.getError('passValidator','password')?.info}}
            </p>          
        </div>          
    </div>
    <p class="form-group">      
        <input type="submit" value="提交" class="btn btn-warning" />      
    </p>      
</form>

二、自定义一个校验方法的步骤

1、把项目中需要用的校验器单独写一个文件

import { FormControl, FormGroup } from '@angular/forms';

    /**
     * 自定义验证器(其实就是一个函数,一个返回任意对象的函数)
     * 传递的参数是当前需要验证的表单的FormControl
     * 通过传递的参数获取当前表单输入的值
     */

     
//手机号校验
export function mobileValidator(control: FormControl): any {
  console.dir(control);
  // 获取到输入框的值
  const val = control.value;
  // 手机号码正则
  const mobieReg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
  const result = mobieReg.test(val);
  return result ? null : { mobile: { info: '手机号码格式不正确' } };
}



//定义一个密码组的校验
export function passValidator(controlGroup: FormGroup): any {
  // 获取密码输入框的值
  const pass1 = controlGroup.get('pass1').value as FormControl;
  const pass2 = controlGroup.get('pass2').value as FormControl;
  console.log('你输入的值:', pass1, pass2);
  const isEqule: boolean = (pass1 === pass2);
  return isEqule ? null : { passValidator: { info: '两次密码不一致' } };
}

2、使用自己定义的校验器=>mobileValidator

createForm() {
  this.myForm = this.fb.group({
    username: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(6)]],
    mobile: ['', [Validators.required, mobileValidator]],
    password: this.fb.group({
      pass1: [''],
      pass2: ['']
    },{validator: passValidator})
  });
}

三、动态调整验证规则

为了演示 “动态调整验证规则” 的功能,我新增了两个控件:

  • radio – 用于让用户设置是否开启手机登录。
  • tel – 当用户开启手机登录功能,用于让用户输入手机号码。

当用户开启手机登录功能,手机号码对应控件的验证规则,必须是必填且格式为合法的手机号码。当用户不开启手机登录功能时,手机号码对应控件将不是必填的。

新增 radio 控件

<div class="form-group">
   <div class="col-md-offset-1 col-md-8 checkbox">
      开启手机登录      <label>
         <input type="radio" value="1"
            formControlName="enableMobile">
              是      </label>
      <label>
         <input type="radio" value="0"
            formControlName="enableMobile">
              否      </label>
   </div></div>

新增 tel 控件

<div class="form-group"
    [ngClass]="{'has-error': (mobile.touched || mobile.dirty) && !mobile.valid }">
          <label class="col-md-2 control-label"
                 for="mobileId">手机号码</label>

          <div class="col-md-8">
            <input class="form-control"
                   id="mobileId"
                   type="text"
                   placeholder="请输入手机号码"
                   formControlName="mobile"/>
            <span class="help-block" *ngIf="(mobile.touched || mobile.dirty) 
               && mobile.errors">
                  <span *ngIf="mobile.errors.required">
                     请输入手机号码
                  </span>
                  <span *ngIf="mobile.errors.minlength">
                     手机号码格式不正确
                  </span>
            </span>
          </div>
</div>

动态调整验证规则功能

ngOnInit(): void {
    ...    this.signupForm.get('enableMobile').valueChanges
      .subscribe(value => this.checkMobile(value));
}

checkMobile(enableMobile: string): void {  const mobileControl = this.signupForm.get('mobile');
  
  enableMobile === "1" ? 
      mobileControl.setValidators([Validators.required,
        Validators.pattern('1(3|4|5|7|8)\\d{9}')]) :
      mobileControl.clearValidators();
  
    mobileControl.updateValueAndValidity();
}

 

 

原文链接 http://www.nbsite.cn/qdjs/168