记录生活中的点滴,分享、学习、创新
一、前提
二、正文
(一)、新建表单(模板表单)
1、新建名称为formValidator的ng项目——命令行输入ng new formValidator;
2、修改pakage.json文件——添加参数,方便开发,命令行输入npm start启动项目;
1 2 3 4 5 6 7 8  | "scripts": { "ng": "ng", "start": "ng serve --open --port 4210",//修改端口号&自动打开默认浏览器窗口 "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, | 
3、新建组件,命令行输入ng g c templateForm --spec false;
4、将app.components.html中的内容,替换成<app-template-form></app-template-form>
5、在app.module.ts中引入FormModul并在import中使用;
6、书写formValidator组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25  | //template-form.html<div class="container"> <form (ngSubmit)="save()" #myForm="ngForm"> <input  type="text"  [(ngModel)]="name" //双向数据绑定  name="name" //使用form时必须定义,可以理解为当前控件的名字  #myName="ngModel" //检查当前控件状态的出口,应用:myName.valid、myName.errors等  autocomplete="off" //关闭浏览器自带的显示历史记录 h5新属性  [appVerifyName]="nameList" //添加验证器 > <!--invalid是否验证成功--> <!--dirty是否改变--> <!--touched是否被抚摸过--> <div *ngIf="myName.invalid && (myName.dirty || myName.touched)">  <div *ngIf="myName.errors.required">   名称为必填项  </div>  <div *ngIf="myName.errors.repeat">   名称重复  </div>  </div> <button type="submit" [disabled]="!myForm.form.valid">提交</button> //验证通过才能提交  </form></div> | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  | //template-form.ts...name: string;nameAry:string[] = ['zhangsan','lisi','wangwu'];constructor() { }ngOnInit() {}save(): void{  console.log('save 发请求')}... | 
(二)、验证表单
1、新建指令,用于验证ng g c d share/verifyName
2、在share目录下新建nameValidator.ts,用于书写验证函数
1 2 3 4 5 6 7 8 9 10 11 12  | //share/nameValidator.tsimport { ValidatorFn, AbstractControl } from "@angular/forms";export function nameValidator(nameList: string[]): ValidatorFn {  return (control: AbstractControl): { [key: string]: any } | null => {    //依据指令中传递进来的名称列表进行判断,如果包含,就返回一个对象,对象的key将    //作为模板(template-form.html)中被验证的控件的erros的key,如果不包含返回null    //表示验证通过    return nameList.includes(control.value) ? { 'repeat': { value: control.value } } : null;  };} | 
3、书写指令——验证名称不能重复
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23  | //verify-name.directive.tsimport { Directive, Input } from '@angular/core';import { Validator, NG_VALIDATORS, AbstractControl } from '@angular/forms';import { nameValidator } from './nameValidator';@Directive({ selector: '[appVerifyName]', providers: [{  provide: NG_VALIDATORS,  useExisting: VerifyNameDirective,  multi: true }]})export class VerifyNameDirective implements Validator { //实现Validator接口 @Input('appVerifyName') //接收验证规则(reg),或者你希望传到指令中的什么 nameList: string[]; validate(control: AbstractControl): { [key: string]: any } | null {  return this.name ? nameValidator(nameList)(control) : null }} | 
三、碎碎念
如果只有一个表单或者项目比较小巧,用这样的验证机制,我认为是不太明智的(用ng都没必要),随便弄个计数器或者标识位就能达到dirty和touched的效果,反之,大概率上没有一个项目有一万个表单控件,定义9000个验证规则的,所以可以高度复用,而且维护起来也灵活一些
总结