如果项目存在多个表单,每次都要手动去判断错误类型及编写错误的提示是非常麻烦的,所以选择用弹框来显示自定义验证规则中的错误提示
有关表单的基础部分的知识就不过多叙述了,有问题看官网: https://www.angular.cn/guide/reactive-forms#generating-form-controls-with-formbuilder
一、编写login.component.html页面
以登陆功能为案例,以下创建的是一个响应式表单
loginForm 这个 FormGroup 也通过 FormGroup 指令绑定到了 form 元素,在该模型和表单中的输入框之间创建了一个通讯层。 由 FormControlName 指令提供的 formControlName 属性把每个输入框和 FormGroup 中定义的表单控件绑定起来。
1 <form class="form" [formGroup]="loginForm" (ngSubmit)="toLogin()" novalidate> 2 <div class="ui-form-item"> 3 <span class="glyphicon glyphicon-user ui-span" aria-hidden="true"></span> 4 <input type="text" class="form-control" placeholder="请输入用户名" formControlName="name" label="用户名" #accountInput> 5 </div> 6 <div class="ui-form-item"> 7 <span class="glyphicon glyphicon-lock ui-span" aria-hidden="true"></span> 8 <input type="password" class="form-control" placeholder="请输入密码" formControlName="paw" label="密码" #passwordInput> 9 </div> 10 <button type="submit" class="btn btn-primary login-btn">登录</button> 11 <a class="register-text" (click)="toRegister()">现在注册</a> 12 </form>
二、编写login.component.ts文件
使用 FormBuilder 来生成表单控件,利用FormBuilder提供的group()方法来创建loginForm控件,每个空间名对应的值是一个数组,这个数组的第一项是其初始值,第二项和第三项提供同步和异步验证器。在构造函数中注入FormBuilder服务。
1 import { FormGroup, FormBuilder, FormControl } from "@angular/forms" 2 3 //登录表单 4 loginForm: FormGroup; 5 6 constructor(private fb: FormBuilder) {} 7 8 //初始化表单 9 initForm() { 10 this.loginForm = this.fb.group({ 11 name: ["", [this.validateService.required]], 12 paw: [null, [this.validateService.required]], 13 }) 14 }
三、自定义验证规则
1.先创建一个服务,命名为validate
2.编写验证规则
required(control: AbstractControl) { var result = (control.value && control.value.trim() !== '' || control.value === 0); return result ? null : { required: { valid: false, text: '不能为空' } }; }
3.验证表单控件
这里的this.until.showPrompt()是一个封装好的提示弹框,具体怎样动态创建组件,请看创建动态组件章节。
//验证控件 valid(control: FormControl, options ? ) { if (options.errorText) { this.until.showPrompt(options.errorText); } else { const errorText = this.getErrorText(control); if (errorText) { const labelName = options && options.labelName || ''; this.until.showPrompt(labelName + errorText); } } } //获取错误 getErrorText(control: FormControl) { if (control.valid) return; const errors = control.errors; //只显示一条错误,优先显示required错误 const error = (errors['required'] && 'required') || Object.keys(errors)[0]; return errors[error].text; }
四、创建属性指令,监听input中的失焦事件
1. 在命令行窗口中创建指令类文件
2.导入相应的包
1 import { Directive, ElementRef, Input, HostListener, OnInit, OnDestroy, Renderer2 } from '@angular/core'; 2 3 import { FormGroup, FormControl, NgControl } from "@angular/forms"; 4 5 import { ValidateService } from "../validate.service";
3.指定指令的选择器
4.监听失焦事件
1 //错误提示文本 2 @Input() errorText = ''; 3 4 //输入框 5 private input: HTMLInputElement; 6 7 constructor( 8 private element: ElementRef, 9 private renderer: Renderer2, 10 private formControl: NgControl, 11 private validateService: ValidateService 12 ) {} 13 14 ngOnInit() { 15 this.input = this.element.nativeElement; 16 17 } 18 19 //监听input元素的失焦事件 20 @HostListener('blur') inputBlur() { 21 if (this.input) { 22 this.valid(); 23 } 24 } 25 26 valid() { 27 let labelName; 28 //获取父元素节点 29 const parentNode = this.renderer.parentNode(this.input); 30 31 //获取label标签节点 32 const label = parentNode && parentNode.querySelector('.ui-label,label'); 33 34 const control = this.formControl.control as FormControl; 35 if (label) { 36 labelName = label.innerText; 37 } else { 38 labelName = this.input.getAttribute('label'); 39 } 40 this.validateService.valid(control, { 41 labelName: labelName, 42 errorText: this.errorText 43 }); 44 }
五、完结
这样就完成了一个自定义表单验证的功能,创建动态组件的部分,下次再写。