视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Angular2 自定义表单验证器的实现方法
2020-11-27 22:02:37 责编:小采
文档


废话

最近由于项目上需要用到表单验证,前面直接通过 (input) 事件进行数据检查,但是不好和自带的验证器统一,而且也不正统。于是打算研究一下自定义验证器,网上类似的文章很多,但是自己在实现的过程中还是遇到了一些问题。于是还是啰嗦的自己写一篇文章。

正文

这里有官方文档:验证响应式表单,用户的视觉提示,自定义验证器,这篇文章是根据这些文档所来(前面两者就不再赘述比较简单,也说的比较清楚)

Angular支持的内置validate属性:

  • required- 设置表单控件值是非空的
  • email - 设置表单控件的格式是email
  • minlength - 设置表单控件值的最小长度
  • maxlength - 设置表单控件长度的最大值
  • pattern - 设置表单控件的值需匹配 pattern 对应的模式
  • 通过表单控件的.valid判断验证结果,其结果状态:

  • valid - 有效
  • invalid - 无效
  • pristine - 表单值未改变
  • dirty - 表单值已改变
  • touched - 表单控件已被访问过
  • untouched- 表单控件未被访问过
  • 我们经常会遇到如下场景,表单验证(样式比较丑陋请忽略)

    现在我们要实现 url 验证,可以直接通过 正则表达式来匹配,这样的话,直接用 Angular 自带的验证器即可,但是如果要兼容大写呢?我们就不能简单的直接使用正则来匹配了,我们需要在判断之前进行一次转换,把内容全部转换成小写,才能进行正则判断。

    这里我们 新建一个 ValidatorBase 类来存放所有的验证,并且新建一个 静态方法 urlValidator(input:FormControl) 来对数据进行 url 验证。具体方法如下:

    import { FormControl } from '@angular/forms';
    import { Injectable } from '@angular/core'
    
    export class ValidateBase{
     public static urlValidator(input: FormControl){
     let validateString = "(https?://|WWW|www|ftp://|file://)[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[.]+[-A-Za-z0-9+&@#/%=~_|]";
    
     console.log(input.value);
     //set value 
     let v = input.value;
    
     if(v!=undefined&&v!="")
     {
     if(v.toLowerCase().match(validateString))
     {
     return null;
     }
     else{
     return {
     isUrl:true
     }
     }
     }
     return null;
     }
    }

    注意:

    这里当匹配成功(即验证成功是需要返回 null 的,不能返回 {isUrl:false},失败是返回的{isUrl:true},不是返回 {isUrl:false}),这样才会让最后表单验证的值为正确的表现。

    这里{isUrl:true} 中的 isUrl,即为传入的 FormControl 的.hasError()中的参数值。

    调用页面

    <form [formGroup]="detailForm" (ngSubmit)="submit()">
     <div>
     <label for="LinkedURL">LinkedURL:</label>
     <input type="LinkedURL" name="LinkedURL" id="LinkedURL" [formControl]="LinkedURL">
     <div class="col-xs-4 col-sm-4" [style.color]="(LinkedURL.touched&&LinkedURL.valid==false)?'#d16e6c':'green'" [hidden]="LinkedURL.untouched">
     <div [hidden]="!LinkedURL.hasError('maxlength')">LinkedURL can not be greater than 250 characters.</div>
     <div [hidden]="!LinkedURL.hasError('isUrl')">LinkedURL is not an url.</div>
     <div [hidden]="!LinkedURL.hasError('required')">Required field.</div>
     <!--Success!-->
     <div [style.color]="'green'" [hidden]="!LinkedURL.valid">Validate success!</div>
     </div>
     </div>
     <button type="submit" [disabled]="!detailForm.valid">Log In</button>
    </form>

    调用页面对应 ts

    import { ValidateBase } from './../../Validators/Validator.base';
    import { Component, OnInit } from '@angular/core';
    
    import {
     FormGroup,
     FormBuilder,
     FormControl,
     Validators
     } from '@angular/forms';
    
    @Component({
     selector: 'validate-component',
     templateUrl: 'validate.component.html'
     })
    
    export class SweepstakesDetailComponent implements OnInit {
    
     private detailForm: FormGroup;
     private LinkedURL: FormControl;
    
     ngOnInit(): void {
     this.validateForm();
     }
    
     private validateForm(){
    
     this.LinkedURL = new FormControl('',[
     Validators.required,
     Validators.maxLength(250),
     ValidateBase.urlValidator
     ]);
    
     //form
     this.detailForm = this.formBuilder.group({
     LinkedURL:this.LinkedURL,
     });
     }
    }

    下载本文
    显示全文
    专题