Angular data13

表单校验

  • 校验器
  • 校验响应式表单
  • 校验模板式表单

1、校验器格式
方法名(control:AbstractControl):{[key]:string:any}{
return null;
}

校验器的参数control必须是AbstractControl类型的,返回的是个对象{};对象的key必须是string类型的,值是any类型的;

默认的校验器是Validators用required,minlength,maxlength等

校验响应式表单 案例

新建组件

ng g component reactRegist

app下新建validator文件夹,新建validators.ts文件
代码如下:


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

import {Observable} from "rxjs/Observable";
//import 'rxjs/add/observable/of';

//自定义手机校验器
export function mobileValidator(control:FormControl):any{
  //手机的正则表达式
  var myreg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
  let valid = myreg.test(control.value);
  console.log("mobile的校验结果是:"+valid);
  return valid ? null:{mobile:true};
}

//异步校验器
export function mobileAsyncValidator(control:FormControl):any{
  //手机的正则表达式
  var myreg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
  let valid = myreg.test(control.value);
  console.log("mobile的校验结果是:"+valid);
  //返回数据流,delay模拟延迟5秒钟返回
  return Observable.of(valid ? null:{mobile:true}).delay(5000) ;
}

//密码校验器
export function equalValidator(group:FormGroup):any{
  //取得密码
  let password:FormControl = group.get("password") as FormControl;
  //取得重复密码
  let pconfirm:FormControl = group.get("pconfirm") as FormControl;
  //比较结果
  let valid:boolean = (password.value === pconfirm.value);
  console.log("密码校验结果:" +valid);
  return valid ? null:{equal:{descxxx:'密码不一致'}};
}

react-regist.component.ts组件代码:

import { Component, OnInit } from '@angular/core';
import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
import {equalValidator, mobileAsyncValidator, mobileValidator} from "../valitator/validators";

@Component({
  selector: 'app-react-regist',
  templateUrl: './react-regist.component.html',
  styleUrls: ['./react-regist.component.css']
})
export class ReactRegistComponent implements OnInit {

  formModel:FormGroup;
  constructor(fb:FormBuilder) {
    this.formModel = fb.group({
      username:['',[Validators.required,Validators.minLength(6)]],
      mobile:['',mobileValidator,mobileAsyncValidator],
      passwordsGroup:fb.group({
        password:['',Validators.minLength(6)],
        pconfirm:[''],
      },{validator:equalValidator})
    });
  }
  onSubmit(){
    /*let isValid:boolean = this.formModel.get('username').valid;
    console.log("username的校验结果:"+isValid);
    let errors:any = this.formModel.get('username').errors;
    //返回校验器的错误信息(含有key)
    console.log("返回的错误信息是:"+JSON.stringify(errors));*/

    if(this.formModel.valid){
      console.log(this.formModel.value);
    }

  }
  ngOnInit() {
  }
}

react-regist.component模块中

<form [formGroup]="formModel" (submit)="onSubmit()">
  <div>
    用户名:<input type="text" formControlName="username">
  </div>
  <!--错误提示-->
  <div [hidden]="!formModel.hasError('required','username')">
    用户名是必填项
  </div>

  <div [hidden]="!formModel.hasError('minlength','username')">
    用户名最小长度是6
  </div>


 <div>
   手机号:<input type="text" formControlName="mobile">
 </div>
  <div [hidden]="!formModel.hasError('mobile','mobile')">
    手机号不正确
  </div>

  <div formGroupName="passwordsGroup">
    <div>
      密码:<input type="password" formControlName="password">
    </div>
    <div>
      重复密码:<input type="password" formControlName="pconfirm" >
    </div>

    <!--错误信息-->
    <div [hidden]="!formModel.hasError('equal','passwordsGroup')">
     {{formModel.getError('equal','passwordsGroup')?.descxxx}}
    </div>
    <div [hidden]="!formModel.hasError('minlength',['passwordsGroup','password'])">
      密码最小长度6位
    </div>

  </div>
  <button type="submit">提交</button>
</form>

<div>
  {{formModel.status}}
</div>

状态字段

  • touched 触摸 未触摸 untouched

关注的字段是有没有获得焦点

  • pristine 值有没有变过 dirty 值有改变过

关注的是字段的值变化

  • pending

当一个字段在异步校验的时候,这时pending的属性是true

通过状态来给字段添加自定义样式

react-regist.component.html重构代码如下:

<form [formGroup]="formModel" (submit)="onSubmit()">
  <div>
    用户名:<input [class.hasError]="formModel.get('username').invalid && formModel.get('username').touched" type="text" formControlName="username">
  </div>

  <!--用户名 错误提示-->
  <div [hidden]="formModel.get('username').valid || formModel.get('username').untouched">
    <div [hidden]="!formModel.hasError('required','username')">
      用户名是必填项
    </div>

    <div [hidden]="!formModel.hasError('minlength','username')">
      用户名最小长度是6
    </div>
  </div>
  <!--用户名 错误提示-->


 <div>
   手机号:<input type="text" formControlName="mobile">
 </div>

  <!-- 手机号 校验提示 -->
  <div [hidden]="formModel.get('mobile').valid || formModel.get('mobile').pristine">
    <div [hidden]="!formModel.hasError('mobile','mobile')">
      手机号不正确
    </div>
  </div>
  <div [hidden]="!formModel.get('mobile').pending">
    正在校验手机号合法性
  </div>
  <!-- 手机号 校验提示 -->

  <div formGroupName="passwordsGroup">
    <div>
      密码:<input type="password" formControlName="password">
    </div>
    <div>
      重复密码:<input type="password" formControlName="pconfirm" >
    </div>

    <!--错误信息-->
    <div [hidden]="!formModel.hasError('equal','passwordsGroup')">
     {{formModel.getError('equal','passwordsGroup')?.descxxx}}
    </div>
    <div [hidden]="!formModel.hasError('minlength',['passwordsGroup','password'])">
      密码最小长度6位
    </div>


  </div>
  <button type="submit">提交</button>
</form>

<div>
  {{formModel.status}}
</div>

react-regist.component.css 代码:

.hasError{
  border: 1px solid palevioletred;
}

校验模板式表单 案例

  • 模板式表单通过自定义指令校验;
  • 自定义指令可以理解为没有模板的组件,使用用@Directive装饰器
  • 自定义指令在HTML中可以当做属性来用

新建组件

ng g component templateForm
ng g directive directives/mobileValidator
ng g directive directives/equalValidator

equal-validator.directive.ts代码:

import { Directive } from '@angular/core';

import {NG_VALIDATORS} from "@angular/forms";
import {equalValidator} from "../valitator/validators";

@Directive({
  selector: '[equal]',
  providers:[{provide:NG_VALIDATORS,useValue:equalValidator,multi:true}]
})
export class EqualValidatorDirective {
  constructor() { }
}

mobile-validator.directive.ts代码:

import { Directive } from '@angular/core';
import {NG_VALIDATORS} from "@angular/forms";
import {mobileValidator} from "../valitator/validators";

@Directive({
  selector: '[mobile]',
  providers:[{provide:NG_VALIDATORS,useValue:mobileValidator,multi:true}]
})
export class MobileValidatorDirective {
  constructor() { }
}

template-form.component.html代码

<form #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value,myForm.valid)" novalidate>
  <div>用户名:<input ngModel required minlength="6" name="username" type="text" (input)="onUserInput(myForm)" ></div>

  <!-- 用户名校验 -->
  <div [hidden]="userValid||userUntouched">
    <div [hidden]="!myForm.form.hasError('required','username')">
      用户名是必填项
    </div>
    <div [hidden]="!myForm.form.hasError('minlength','username')">
      用户名最小长度是6
    </div>
  </div>

template-form.component.ts代码

import {Component, OnInit} from '@angular/core';
import {NgForm} from "@angular/forms";

@Component({
  selector: 'app-template-form',
  templateUrl: './template-form.component.html',
  styleUrls: ['./template-form.component.css']
})
export class TemplateFormComponent implements OnInit {

  constructor() {
  }
  ngOnInit() {
  }

  mobileValid: boolean = true;
  mobileUntouched: boolean = true;
  onMobileInput(form: NgForm) {
    if (form) {
      this.mobileValid = form.form.get('mobile').valid;
      this.mobileUntouched = form.form.get('mobile').untouched;
    }
  }

  userValid: boolean = true;
  userUntouched: boolean = true;
  onUserInput(form: NgForm) {
    if (form) {
      this.userValid = form.form.get('username').valid;
      this.userUntouched = form.form.get('username').untouched;
    }
  }

  onSubmit(value: any, valid: boolean) {
    console.log(valid);
    console.log(value);
  }
}

源码 链接:http://pan.baidu.com/s/1cpWvW6 密码:zhog

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 史上最简单Angular2教程,大叔都学会了 作者:王芃 wpcfan@gmail.com 第一节:初识Angul...
    接灰的电子产品阅读 58,921评论 76 248
  • 本文将介绍如何动态创建表单组件,我们最终实现的效果如下: 在阅读本文之前,请确保你已经掌握 Angular 响应式...
    semlinker阅读 3,906评论 0 7
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,812评论 25 709
  • 火车悠悠地行驶着,窗外的景色不断在变化。 五年了,终于要来到他生活的城市,她魂牵梦绕的城市。都说是因为一个...
    两三点水阅读 821评论 5 2
  • 一直以来,我都在思所着同一个问题——究竟我能不能靠自己一个人好好的生活?我在怕什么?又在担忧什么?恐惧什么?我越来...
    雪铃航阅读 307评论 0 1