angular已经集成了完善的表单验证体系,可以直接引入使用即可,十分方便。
表单分为两种,一种是响应式表单,一种是模板式表单。
响应式表单就是表单的字段在js中声明,而模板式表单则在html中通过双向绑定来声明。
我们通常开发使用的是响应式表单,因为这样比较直观。
响应式表单验证,分为这么几种类型:
单个字段——formControl
formControl对象是针对表单的单个字段来验证的。
我们创建一个组件来玩一下:
ng g component components/formcontrol
formcontrol.component.ts:
import { Component, OnInit } from '@angular/core';
import { FormControl,Validators } from '@angular/forms';
@Component({
selector: 'app-formcontrol',
templateUrl: './formcontrol.component.html',
styleUrls: ['./formcontrol.component.css']
})
export class FormcontrolComponent implements OnInit {
username = new FormControl('',[ //声明验证规则
Validators.required,
Validators.minLength(6),
]);
constructor() { }
ngOnInit(): void {
console.log(this.username);
}
}
formcontrol.component.html:
<div>
用户名:{{username.value}}
<input type="text" [formControl] = "username" /> <br />
</div>
<div *ngIf="username.invalid && (username.dirty || username.touched)">
<div *ngIf="username.errors.required">
用户名必填!
</div>
<div *ngIf="username.errors.minlength">
字符不少于6位!
</div>
</div>
但通常情况下是针对一组字段进行验证的,因此就有了formGroup。
多个字段验证——formGroup
一般常用的是formGroup,针对多个字段进行统一验证。
ng g component components/formgroup
formgroup.component.ts:
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup,Validators } from '@angular/forms';
@Component({
selector: 'app-formgroup',
templateUrl: './formgroup.component.html',
styleUrls: ['./formgroup.component.css']
})
export class FormgroupComponent implements OnInit {
formData = new FormGroup({
username: new FormControl('',[ //必填
Validators.required
]),
passwd: new FormControl('',[ //必填、不少于6位
Validators.required,
Validators.minLength(6),
]),
email: new FormControl('',[
Validators.required,
this.emailValueValidator //自定义验证规则
])
})
constructor() { }
ngOnInit(): void {
}
//自定义验证规则
emailValueValidator(control: FormControl): any {
let reg = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
if (!reg.test(control.value)) {
return { value: {info: '邮箱格式不正确'} };
}
}
sub(data){
console.log('finall>>>',data)
}
}
formgroup.component.html:
<form [formGroup]="formData" (ngSubmit)="sub(formData.value)">
<div>
用户名:
<input type="text" formControlName="username" />
<div [hidden]="formData.get('username').valid || formData.get('username').untouched">
<p [hidden]="!formData.hasError('required', 'username')">用户名必填!</p>
</div>
</div>
<div>
密码:
<input type="passwd" formControlName="passwd" />
<div [hidden]="formData.get('passwd').valid || formData.get('passwd').untouched" class="small">
<p [hidden]="!formData.hasError('required', 'passwd')">必填项</p>
<p [hidden]="!formData.hasError('minlength', 'passwd')"> 密码不少于6位!</p>
</div>
</div>
<div>
邮箱:
<input type="text" formControlName="email" />
<div [hidden]="formData.get('email').valid || formData.get('email').untouched" class="small">
<p [hidden]="!formData.hasError('required', 'email')">必填项</p>
<p [hidden]="!formData.hasError('value', 'email')">{{formData.getError('value', 'email')?.info}}</p>
</div>
</div>
<div>
<button type="submit" [disabled]="!formData.valid" class="btn btn-sm btn-primary">提交</button>
</div>
</form>
formGroup有一定的局限性,因为它必须事先约定所有字段的名称、验证规则等信息,如果要动态添加某些字段怎么办?这时formBuilder就派上了用场。
动态添加字段——formBuilder
formBuilder提供了一个FormArray()方法,看名字就知道它是一个数组,添加新字段,不过是往数组push一条数据罢了。
ng g component components/formbuilder
formgroup.component.ts:
import { Component, OnInit } from '@angular/core';
import { FormBuilder,FormArray,Validators } from '@angular/forms';
@Component({
selector: 'app-formbuilder',
templateUrl: './formbuilder.component.html',
styleUrls: ['./formbuilder.component.css']
})
export class FormbuilderComponent implements OnInit {
constructor(private fb: FormBuilder) { } // 初始化
formData = this.fb.group({
username: ['', [Validators.required]],
passwd:[ '',[Validators.required,Validators.minLength(6)]],
interest:this.fb.array([
this.fb.control('')
])
})
get interest(){
return this.formData.get('interest') as FormArray;
}
addInterest(){
this.interest.push(this.fb.control(''))
console.log(this.interest)
}
sub(data){
console.log('finall>>>',data)
}
ngOnInit(): void {
console.log(this.formData)
}
}
formgroup.component.html:
<form [formGroup]="formData" (ngSubmit)="sub(formData.value)">
<div>
用户名:
<input type="text" formControlName="username" />
<div [hidden]="formData.get('username').valid || formData.get('username').untouched">
<p [hidden]="!formData.hasError('required', 'username')">用户名必填!</p>
</div>
</div>
<div>
密码:
<input type="passwd" formControlName="passwd" />
<div [hidden]="formData.get('passwd').valid || formData.get('passwd').untouched" class="small">
<p [hidden]="!formData.hasError('required', 'passwd')">必填项</p>
<p [hidden]="!formData.hasError('minlength', 'passwd')"> 密码不少于6位!</p>
</div>
</div>
<div formArrayName="interest">
<button (click)="addInterest()">+增加</button>
<div *ngFor="let item of interest.controls; let k=index">
<div>
兴趣:
<input type="text" [formControlName]="k" />
</div>
</div>
</div>
<div>
<button type="submit" [disabled]="!formData.valid" class="btn btn-sm btn-primary">提交</button>
</div>
</form>
可以看出,使用formBuilder构建表单还是比较方便的。