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('[email protected]'),
new FormControl('[email protected]')
])
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>