1.模板式表单
template-form.component.html
<form #myForm="ngForm" (ngSubmit)="onsubmit(myForm.value)">
<div>用户名:<input ngModel name="username" type="text"></div>
<div>手机号:<input ngModel name="phone" type="text"></div>
<div>邮编:<input type="number"></div>
<div ngModelGroup="passwordsGroup">
<div>密码::<input ngModel name="password" type="password"></div>
<div>确认密码:<input ngModel name="pconfirm" type="password"></div>
</div>
<button type="submit">注册</button>
</form>
<div>
{{myForm.value | json}}
</div>
template-form.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-template-form',
templateUrl: './template-form.component.html',
styleUrls: ['./template-form.component.css']
})
export class TemplateFormComponent implements OnInit {
constructor() { }
ngOnInit() {
}
onsubmit(value: any){
console.log(value);
}
}
2.响应式表单
1.
reactive-form.component.html
<form [formGroup]="formModel" (submit)="onSubmit()">
<div formGroupName="dateRange">
起始日期:<input type="date">
截止日期:<input type="date">
</div>
<div>
<ul>
<li>
<input type="text">
</li>
</ul>
<button type="button">增加Email</button>
</div>
<button type="submit">保存</button>
</form>
reactive-form.component.ts
import { Component, OnInit } from '@angular/core';
import {FormArray, FormControl, FormGroup} from '@angular/forms';
@Component({
selector: 'app-reactive-form',
templateUrl: './reactive-form.component.html',
styleUrls: ['./reactive-form.component.css']
})
export class ReactiveFormComponent implements OnInit {
/*指定初始值 */
username: FormControl = new FormControl('aaa');
/*formModel:表示整个表单的数据*/
formModel:FormGroup = new FormGroup({
dateRange: new FormGroup({
from: new FormControl(),
to: new FormControl()
})
});
emails: FormArray = new FormArray([
new FormControl('a@a.com'),
new FormControl('b@b.com')
])
constructor() { }
ngOnInit() {
}
onSubmit() {
console.log(this.formModel.value);
}
}
2.
reactive-regist.component.html
<form [formGroup]="formModel" (submit)="onSubmit()">
<div>用户名:<input type="text" formControlName="username"></div>
<div>手机号:<input type="text" formControlName="mobile"></div>
<div formGroupName="passwordsGroup">
<div>密码::<input type="text" formControlName="password"></div>
<div>确认密码:<input type="text" formControlName="pconfirm"></div>
</div>
<button type="submit">注册</button>
</form>
reactive-regist.component.ts
import { Component, OnInit } from '@angular/core';
import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
@Component({
selector: 'app-reactive-regist',
templateUrl: './reactive-regist.component.html',
styleUrls: ['./reactive-regist.component.css']
})
export class ReactiveRegistComponent implements OnInit {
formModel: FormGroup;
/*1.new 关键字实例化表单模型的类*/
/*constructor() {
this.formModel = new FormGroup({
username: new FormControl(),
mobile: new FormControl(),
passwordsGroup: new FormGroup({
password: new FormControl(),
pconfirm: new FormControl()
})
})
}*/
/*2.FormBuilder配置表单模型*/
constructor(fb: FormBuilder) {
this.formModel = fb.group({
username: [''],
mobile: [''],
passwordsGroup: fb.group({
password: [''],
pconfirm: ['']
})
})
}
ngOnInit() {
}
onSubmit(){
console.log(this.formModel.value);
}
}
3.表单校验
3.1Angular校验器
xxxx(control:AbstractControl):{ [key:string] :any} {
Validators.xxx
return null ;
}
3.2校验响应式表单
reactive-regist.component.ts
import { Component, OnInit } from '@angular/core';
import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
@Component({
selector: 'app-reactive-regist',
templateUrl: './reactive-regist.component.html',
styleUrls: ['./reactive-regist.component.css']
})
export class ReactiveRegistComponent implements OnInit {
formModel: FormGroup;
/*2.FormBuilder配置表单模型*/
constructor(fb: FormBuilder) {
this.formModel = fb.group({
username: ['', [Validators.required, Validators.minLength(6)]],
mobile: [''],
passwordsGroup: fb.group({
password: [''],
pconfirm: ['']
})
})
}
onSubmit(){
let isValid: boolean = this.formModel.get("username").valid;
console.log("username的校验结果是:"+isValid);
let errors: any = this.formModel.get("username").errors;
console.log("username的错误信息是:"+JSON.stringify(errors));
console.log(this.formModel.value);
}
ngOnInit() {
}
}
自定义校验器
创建文件夹:validator–》ts文件:validators.ts
validators.ts
/**
* Created by Administrator on 2019/1/3/003.
*/
import {AbstractControl, FormControl, FormGroup} from "@angular/forms";
import {of} from 'rxjs';
import {delay} from 'rxjs/operators';
/*全局的typescript的函数*/
export function mobileValidator(control: AbstractControl) :{ [key: string] :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: AbstractControl) :{ [key: string] :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 of(valid ? null : {mobile: true}).pipe(
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: {describle:"密码和确认密码不匹配"}};
}
reactive-regist.component.ts
import { Component, OnInit } from '@angular/core';
import {AbstractControl, FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
import {equalValidator, mobileAsyncValidator, mobileValidator} from "../validator/validators";
@Component({
selector: 'app-reactive-regist',
templateUrl: './reactive-regist.component.html',
styleUrls: ['./reactive-regist.component.css']
})
export class ReactiveRegistComponent implements OnInit {
formModel: FormGroup;
/*2.FormBuilder配置表单模型*/
constructor(fb: FormBuilder) {
this.formModel = fb.group({
username: ['', [Validators.required, Validators.minLength(6)]],
/*异步校验器可以作为formControl第三个构造函数传入模型*/
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;
console.log("username的错误信息是:"+JSON.stringify(errors));
if(this.formModel.valid){
/*全部通过验证*/
console.log(this.formModel.value);
}
}
ngOnInit() {
}
}
reactive-regist.component.html
<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="text" formControlName="password"></div>
<div [hidden]="!formModel.hasError('minlength',['passwordsGroup','password'])">
密码最小长度是6
</div>
<div>确认密码:<input type="text" formControlName="pconfirm"></div>
<div [hidden]="!formModel.hasError('equal','passwordsGroup')">
{{formModel.getError('equal','passwordsGroup')?.describle}}
</div>
</div>
<button type="submit">注册</button>
</form>
<!--异步校验器-->
<div>
{{formModel.status}}
</div>
状态字段
touched、untouched
是否获取过焦点
<div>用户名:<input 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>
pristine、dirty
是否改变过,修改过false,true
<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>
pending
<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>
字段处于异步校验时,true
3.3校验模板式表单
1.生成指令
–> ng g directive directives/mmobileValidator
–> ng g directive directives/equalValidator
mmobileValidator.directive.ts
import { Directive } from '@angular/core';
import {NG_VALIDATORS} from "@angular/forms";
import {mobileValidator} from "../validator/validators";
@Directive({
selector: '[mobile]',
providers: [{provide: NG_VALIDATORS, useValue: mobileValidator, multi: true}]
})
export class MmobileValidatorDirective {
constructor() { }
}
equalValidator.directive.ts
import { Directive } from '@angular/core';
import {NG_VALIDATORS} from "@angular/forms";
import {equalValidator} from "../validator/validators";
@Directive({
selector: '[equal]',
providers: [{provide: NG_VALIDATORS, useValue: equalValidator, multi: true}]
})
export class EqualValidatorDirective {
constructor() { }
}
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 {
mobileValid: boolean =true;
mobileUntouched: boolean=true;
constructor() { }
ngOnInit() {
}
onsubmit(value: any,valid: boolean){
/*console.log(value);
console.log(valid);*/
}
onMobileInput(form: NgForm){
if(form){
this.mobileValid = form.form.get("mobile").valid;
this.mobileUntouched = form.form.get("mobile").untouched;
}
}
}
template-form.component.html
<!--novalidate:不要启动浏览器默认的表单校验-->
<form #myForm="ngForm" (ngSubmit)="onsubmit(myForm.value,myForm.valid)" novalidate>
<div>用户名:<input ngModel required minlength="6" name="username" type="text" (input)="onMobileInput(myForm)"></div>
<div [hidden]="mobileValid || mobileUntouched">
<div [hidden]="!myForm.form.hasError('required','username')">
用户名是必填项
</div>
<div [hidden]="!myForm.form.hasError('minlength','username')">
用户名最小长度是6
</div>
</div>
<div>手机号:<input ngModel mobile name="mobile" type="text"></div>
<div [hidden]="!myForm.form.hasError('mobile','mobile')">
请输入正确的手机号
</div>
<div>邮编:<input type="number"></div>
<div ngModelGroup="passwordsGroup" equal>
<div>密码::<input ngModel minlength="6" name="password" type="password"></div>
<div [hidden]="!myForm.form.hasError('minlength',['passwordsGroup','password'])">
密码最小长度是6
</div>
<div>确认密码:<input ngModel name="pconfirm" type="password"></div>
<div [hidden]="!myForm.form.hasError('equal','passwordsGroup')">
{{myForm.form.getError('equal','passwordsGroup')?.describle}}
</div>
</div>
<button type="submit">注册</button>
</form>
<div>
<!--{{myForm.value | json}}-->
</div>