<1>angular表單API
不同點
注意
要使用angular表單柠偶,要在app.module.ts中引入相應(yīng)的模塊
模版式表單:FormsModule
響應(yīng)式表單:ReactiveFormsModule
<2>模版式表單
使用模版式表單時位隶,只能使用指令來定義數(shù)據(jù)模型。
(1)NgForm
用來代表整個表單树枫,在angular項目中,它會自動添加到每個form標(biāo)簽上藤树。
示例:
1.新建一個組件
ng g component templateForm
2.修改template-form.component.html
<form action="/action" method="POST">
<p>用戶名:<input type="text"></p>
<p>手機(jī)號:<input type="text"></p>
<p>密碼:<input type="password"></p>
<p>確認(rèn)密碼:<input type="password"></p>
<button type="submit">提交</button>
</form>
3.修改app.component.html
<app-template-form></app-template-form>
4.修改app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { TemplateFormComponent } from './template-form/template-form.component';
import { NgModule } from '@angular/core';
// 引入
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent,
TemplateFormComponent
],
imports: [
BrowserModule,
// 添加
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
5.界面
在非angular接管的表單中形耗,點擊提交,url會變成:localhost:4200/action碍沐,
而angular接管的表單中狸捅,點擊提交url不會有變化。
若想要指定form不被angular接管累提,可以定義:
<!-- 添加ngNoForm表示此表達(dá)不讓angular接管 -->
<form action="/action" method="POST" ngNoForm>
<p>用戶名:<input type="text"></p>
<p>手機(jī)號:<input type="text"></p>
<p>密碼:<input type="password"></p>
<p>確認(rèn)密碼:<input type="password"></p>
<button type="submit">提交</button>
</form>
特性:ngForm指令可以被一個模版本地變量引用尘喝,以便在模版中訪問ngForm對象的實例。
例子:
1.修改template-form.component.html
<!-- 聲明一個模板變量#myForm -->
<form #myForm=ngForm action="/action" method="POST">
<p>用戶名:<input type="text"></p>
<p>手機(jī)號:<input type="text"></p>
<p>密碼:<input type="password"></p>
<p>確認(rèn)密碼:<input type="password"></p>
<button type="submit">提交</button>
</form>
<!-- 下面通過這個模板變量來訪問ngForm對象的屬性 -->
<!-- value是一個js對象斋陪,它保存了當(dāng)前表單里面的值 -->
{{myForm.value | json}}
2.結(jié)果
(2)NgModel
ngModel指令代表表單中的一個字段朽褪,這個指令會隱式的創(chuàng)建一個FormControl的實例,來代表字段的數(shù)據(jù)模型无虚,并用這個FormControl類型的對象來存儲字段的值缔赠。
在上面例子的json中,當(dāng)在表單中輸入值時沒有加到j(luò)son中顯示的原因是友题,那些input標(biāo)簽并未綁定ngModel指令嗤堰。
注意
在ngForm中使用ngModel不需要像普通的數(shù)據(jù)雙向綁定那樣用[(ngModel)]的方式,直接寫ngModel即可
ngModel也可以使用模版變量來獲取它的值
示例
1.
<!-- 聲明一個模板變量#myForm -->
<form #myForm="ngForm" action="/action" method="POST">
<!-- 給用戶名綁定ngModel,并且聲明一個模板變量#user -->
<!-- 注意度宦,一定要給標(biāo)簽聲明一個name屬性 -->
<p>用戶名:<input #user="ngModel" ngModel name="username" type="text"></p>
<p>手機(jī)號:<input type="text"></p>
<p>密碼:<input type="password"></p>
<p>確認(rèn)密碼:<input type="password"></p>
<button type="submit">提交</button>
</form>
<!-- 下面通過這個模板變量來訪問ngForm對象的屬性 -->
<!-- value是一個js對象踢匣,它保存了當(dāng)前表單里面的值 -->
{{myForm.value | json}}
<!-- 用#user模板變量來獲取用戶名的值 -->
{{username.value}}
2.結(jié)果
此時再次輸入用戶名時就會實時反映到下面的json中
當(dāng)應(yīng)用為單頁應(yīng)用并不需要跳轉(zhuǎn)網(wǎng)頁時告匠,往往用ngSubmit來替代form標(biāo)簽的提交作用
示例
1.修改template-form.component.html
<!-- 綁定ngSubmit,并定義一個方法fun,傳入myForm的值到后臺 -->
<form #myForm="ngForm" (ngSubmit)="fun(myForm.value)" action="/action" method="POST">
<p>用戶名:<input #user="ngModel" ngModel name="username" type="text"></p>
<p>手機(jī)號:<input type="text"></p>
<p>密碼:<input type="password"></p>
<p>確認(rèn)密碼:<input type="password"></p>
<button type="submit">提交</button>
</form>
{{myForm.value | json}}
{{username.value}}
2.修改template-form.component.spec.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);
}
}
(3)NgModelGroup
代表的是表單的一部分,它允許你將一些表單字段組織在一起离唬,形成一個更清晰的層次關(guān)系凫海,與ngForm指令類似,ngModelGroup指令也會創(chuàng)建一個FormGroup類的一個實例男娄,這個實例會在ngForm對象的value屬性中表現(xiàn)為一個嵌套的對象,所以說ngModelGroup的子屬性都會變?yōu)檫@個嵌套對象的子屬性
示例
1.修改template-form.component.html
<form #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value)">
<!-- 嵌套一個ngModelGroup -->
<div ngModelGroup="userInfo">
<p>用戶名:<input #user="ngModel" ngModel name="username" type="text"></p>
<p>手機(jī)號:<input type="text"></p>
</div>
<p>密碼:<input type="password"></p>
<p>確認(rèn)密碼:<input type="password"></p>
<button type="submit">提交</button>
</form>
<!-- 下面通過這個模板變量來訪問ngForm對象的屬性 -->
<!-- value是一個js對象漾稀,它保存了當(dāng)前表單里面的值 -->
{{myForm.value | json}}
<!-- 用#user模板變量來獲取用戶名的值 -->
{{username.value}}
2.結(jié)果
username就被嵌套在userInfo中成為了userInfo的一個屬性模闲。
(4)重構(gòu)用戶注冊表單的案例
1.修改template-form.component.html
<form #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value)">
<div ngModelGroup="userInfo">
<p>用戶名:<input #user="ngModel" ngModel name="username" type="text"></p>
<p>手機(jī)號:<input ngModel name="phone" type="text"></p>
</div>
<!-- 嵌套一個ngModelGroup -->
<div ngModelGroup="passwordsGroup">
<p>密碼:<input ngModel name="password" type="password"></p>
<p>確認(rèn)密碼:<input ngModel name="pconfirm" type="password"></p>
</div>
<button type="submit">提交</button>
</form>
2.結(jié)果
當(dāng)輸入結(jié)束,點擊提交時
<3>響應(yīng)式表單
與模版式表單不同崭捍,創(chuàng)建一個響應(yīng)式表單需要兩步尸折,首先需要編碼來創(chuàng)建一個數(shù)據(jù)模型,然后需要使用些指令將模版中的html元素連接到這個數(shù)據(jù)模型上殷蛇。
1实夹、數(shù)據(jù)模型
是指用來保存表單數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu),簡稱模型粒梦。它由定義在angular的forms模塊中的三個類組成亮航。分別是:FormCotrol,F(xiàn)ormGroup匀们,F(xiàn)ormArray
(1)FormCotrol:是構(gòu)成表單的基本單位缴淋,通常情況下它用來代表一個input元素,它也可以用來代表一個更復(fù)雜的UI組件泄朴,比如說日歷重抖、下拉選擇塊等。FormCotrol保存著與其關(guān)聯(lián)的html元素當(dāng)前的值以及元素的校驗狀態(tài)祖灰,還有元素是否被修改過等信息钟沛。
如何創(chuàng)建一個FormCotrol,示例:
//其中FormCotrol接收的參數(shù)aaa是username的初始值
username:FormCotrol = new FormCotrol("aaa");
(2)FormGroup:FormGroup既可以代表表單的一部分也可以用于代表整個表單局扶,它是多個FormCotrol的集合恨统,F(xiàn)ormGroup將多個FormCotrol的值和狀態(tài)聚合在一起。如果一個FormCotrol是無效的详民,那么整個FormGroup都是無效的延欠。
優(yōu)點:在管理表單中多個相關(guān)聯(lián)的字段時,使用FormGroup是很方便的沈跨,比如一個日期范圍由捎,有起始和終止日期兩個input,這兩個input可以放到一個FormGroup中饿凛,當(dāng)其中一個任何一個字段的值無效時都會顯示一個錯誤信息狞玛。
如何創(chuàng)建一個FormGroup软驰,示例:
//FormGroup的構(gòu)造函數(shù)需要一個對象
formModel:FormGroup = new FormGroup({
fromDate: new FormCotrol(),
toDate: new FormCotrol()
});
(3)FormArray:FormArray和FormGroup是類似的,但是它有一個額外的長度屬性心肪,一般來說FormGroup用來代表整個表單或者表單字段的一個固定的子集锭亏。而FormArray通常用來代表一個可以增長的字段集合。
如何創(chuàng)建一個FormArray硬鞍,示例:
//FormArray的構(gòu)造函數(shù)是一個數(shù)組
emails:FormArray = new FormArray([
new FormCotrol("a@qq.com"),
new FormCotrol("b@qq.com")
]);
2慧瘤、響應(yīng)式表單指令
使用時,上圖第二列要用屬性綁定語法固该,即[formGroup]的形式锅减,而第三列不需要用屬性綁定語法。
示例
1.修改app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { ReactiveFormComponent } from './reactive-form/reactive-form.component';
// 引入響應(yīng)式表單
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent,
ReactiveFormComponent
],
imports: [
BrowserModule,
//引入
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
2.修改reactive-form.component.ts
import { Component, OnInit } from '@angular/core';
//引入文件
import { FormGroup,FormControl,FormArray } from '@angular/forms';
@Component({
selector: 'app-reactive-form',
templateUrl: './reactive-form.component.html',
styleUrls: ['./reactive-form.component.css']
})
export class ReactiveFormComponent implements OnInit {
// 1.定義一個名為"myFormModel"的formGroup伐坏,用它來表示整個表單
myFormModel:FormGroup = new FormGroup({
// 3.聲明一個formGroup,里面包含兩個FormControl
dateRange: new FormGroup({
formDate:new FormControl(),
toDate:new FormControl()
}),
emails:new FormArray([
new FormControl("a@qq.com"),
new FormControl("b@qq.com"),
new FormControl("c@qq.com")
]),
username2:new FormControl("name2")
});
// 5.定義一個名為username的FormControl
username:FormControl = new FormControl("namenamename");
constructor() { }
ngOnInit() {
}
// 2.處理保存方法怔匣,打印myFormModel的值
mySubmit(){
console.log(this.myFormModel.value);
}
// 4.增加郵箱方法
addEmail(){
let emails = this.myFormModel.get("emails") as FormArray;
emails.push(new FormControl());
}
}
3.修改reactive-form.component.html
<!--
1.通常情況下,會用一個綁定到form標(biāo)簽的formGroup對象來代表整個表單
用formGroup屬性綁定到后臺定義的myFormModel
這樣就把整個表單的處理方式變成了響應(yīng)式表單的處理方式
-->
<!-- 2.提交方法 -->
<form [formGroup] = "myFormModel" (submit)="mySubmit()">
<!-- 3.用formGroupName來連接一個formGroup -->
<div formGroupName="dateRange">
<!--
4.formControlName必須聲明在formGroup內(nèi)桦沉,來連接formGroup中的formControl和頁面上的dom元素
-->
起始日期:<input type="date" formControlName="formDate"><br><br>
截至日期:<input type="date" formControlName="toDate">
</div>
<!-- 5.formArrayName也必須放在formGroup范圍內(nèi) -->
<div>
<ul formArrayName="emails">
<!-- 6.因為FormArray是用下標(biāo)來顯示每條數(shù)據(jù)的每瞒,所以一般配合ngFor來一起使用 -->
<li *ngFor="let e of this.myFormModel.get('emails').controls;let i = index;" style="list-style: none">
<!-- 這里要用屬性綁定[formControlName] -->
郵箱:<input type="text" [formControlName] = "i"><br>
</li>
</ul>
<!-- 7.綁定click事件 -->
<button type="button" (click)="addEmail()">增加email</button>
</div>
<div>
<br>
<button type="submit">保存</button>
</div>
<!-- 9.這種方式才會在formGroup的數(shù)據(jù)模型里 -->
<input type="text" formControlName = "username2">
</form>
<br>
<!--
8.formControl指令不能放在formGroup的內(nèi)部
這個username不在formGroup里,所以點擊保存不會打印出來
-->
<input type="text" [formControl] = "username">
4.結(jié)果
3纯露、響應(yīng)式表單重構(gòu)用戶注冊表
1.修改app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { ReactiveRigistComponent } from './reactive-rigist/reactive-rigist.component';
//引入響應(yīng)式表單
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent,
ReactiveRigistComponent
],
imports: [
BrowserModule,
//引入響應(yīng)式表單
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
2.修改reactive-rigist.component.html
<form [formGroup] = "myFormGroup">
<p>用戶名:<input type="text" formControlName = "username"></p>
<p>手機(jī)號:<input type="text" formControlName = "mobile"></p>
<div formGroupName = "passwordGroup">
<p>密碼:<input type="password" formControlName = "pwd"></p>
<p>確認(rèn)密碼:<input type="password" formControlName = "pconfirm"></p>
</div>
<button type="submit" (click) = "mySubmit()">提交</button>
</form>
3.修改reactive-rigist.component.ts
import { Component, OnInit } from '@angular/core';
//引入
import { FormGroup,FormControl } from '@angular/forms';
@Component({
selector: 'app-reactive-rigist',
templateUrl: './reactive-rigist.component.html',
styleUrls: ['./reactive-rigist.component.css']
})
export class ReactiveRigistComponent implements OnInit {
myFormGroup:FormGroup;
constructor() {
this.myFormGroup = new FormGroup({
username:new FormControl(),
mobile:new FormControl(),
passwordGroup:new FormGroup({
pwd:new FormControl(),
pconfirm:new FormControl()
})
})
}
mySubmit(){
console.log(this.myFormGroup.value);
}
ngOnInit() {
}
}
4.結(jié)果
formBuilder
將上個例子中的
constructor() {
this.myFormGroup = new FormGroup({
username:new FormControl(),
mobile:new FormControl(),
passwordGroup:new FormGroup({
pwd:new FormControl(),
pconfirm:new FormControl()
})
})
}
用 formBuilder 替換后
constructor(fb:FormBuilder) {
this.myFormGroup = fb.group({
username:[''],
mobile:[''],
passwordGroup:fb.group({
pwd:[''],
pconfirm:['']
})
})
}
最終的效果是一樣的剿骨。
<4>表單校驗
1、angular的校驗器
校驗器就是一個普通的方法苔埋,該方法接收一個參數(shù)懦砂,參數(shù)類型必須為AbstractControl,必須要有一個返回值组橄,返回值可以是任意結(jié)構(gòu)的一個對象荞膘,這個對象的key必須是string類型的。
例如:
xxxx(control:AbstractControl):{[key:string]:any} {
return null;
}
angular自帶校驗器例子:
import { Component, OnInit} from '@angular/core';
//引入
import { FormGroup,FormControl,FormBuilder,Validators } from '@angular/forms';
@Component({
selector: 'app-reactive-rigist',
templateUrl: './reactive-rigist.component.html',
styleUrls: ['./reactive-rigist.component.css']
})
export class ReactiveRigistComponent implements OnInit {
myFormGroup:FormGroup;
constructor(fb:FormBuilder) {
this.myFormGroup = fb.group({
// 第一個是默認(rèn)值玉工,第二個是校驗器
// 單個校驗器的寫法
// username:['',[Validators.required,Validators.minLength(6)]],
// 多個校驗器的寫法
username:['',[Validators.required,Validators.minLength(6)]],
mobile:[''],
passwordGroup:fb.group({
pwd:[''],
pconfirm:['']
})
})
}
mySubmit(){
let isValid:boolean = this.myFormGroup.get("username").valid;
console.log("username的校驗結(jié)果"+isValid);
let errors:any = this.myFormGroup.get("username").errors;
console.log("username的錯誤信息是"+JSON.stringify(errors));
console.log(this.myFormGroup.value);
}
ngOnInit() {
}
}
結(jié)果
2羽资、自定義校驗器
1.
import { Component, OnInit} from '@angular/core';
//引入
import { FormGroup,FormControl,FormBuilder,Validators } from '@angular/forms';
@Component({
selector: 'app-reactive-rigist',
templateUrl: './reactive-rigist.component.html',
styleUrls: ['./reactive-rigist.component.css']
})
export class ReactiveRigistComponent implements OnInit {
//自定義手機(jī)號校驗器
mobileValidator(control:FormControl):any {
// 手機(jī)號正則表達(dá)式
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的校驗結(jié)果是:"+valid);
return valid ? null : {mobile : true};
}
myFormGroup:FormGroup;
constructor(fb:FormBuilder) {
this.myFormGroup = fb.group({
username:['',[Validators.required,Validators.minLength(6)]],
//添加自定義的校驗器
mobile:['',this.mobileValidator],
passwordGroup:fb.group({
pwd:[''],
pconfirm:['']
})
})
}
mySubmit(){
let isValid:boolean = this.myFormGroup.get("username").valid;
console.log("username的校驗結(jié)果"+isValid);
let errors:any = this.myFormGroup.get("username").errors;
console.log("username的錯誤信息是"+JSON.stringify(errors));
console.log(this.myFormGroup.value);
}
ngOnInit() {
}
}
2、結(jié)果
3遵班、為FormGroup自定義校驗器
1屠升、
import { Component, OnInit} from '@angular/core';
//引入
import { FormGroup,FormControl,FormBuilder,Validators } from '@angular/forms';
@Component({
selector: 'app-reactive-rigist',
templateUrl: './reactive-rigist.component.html',
styleUrls: ['./reactive-rigist.component.css']
})
export class ReactiveRigistComponent implements OnInit {
mobileValidator(control:FormControl):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的校驗結(jié)果是:"+valid);
return valid ? null : {mobile : true};
}
//自定義方法
equalValidator(group:FormGroup):any {
let pwd:FormControl = group.get("pwd") as FormControl;
let pconfirm:FormControl = group.get("pconfirm") as FormControl;
let valid:boolean = (pwd.value === pconfirm.value);
console.log("密碼校驗結(jié)果:"+valid);
// 當(dāng)校驗通過時返回null,當(dāng)校驗不通過的時候返回{equal : true}
return valid ? null : {equal : true};
}
myFormGroup:FormGroup;
constructor(fb:FormBuilder) {
this.myFormGroup = fb.group({
username:['',[Validators.required,Validators.minLength(6)]],
mobile:['',this.mobileValidator],
passwordGroup:fb.group({
pwd:[''],
pconfirm:['']
// 加入聲明,是一個對象
},{validator:this.equalValidator})
})
}
mySubmit(){
let isValid:boolean = this.myFormGroup.get("username").valid;
console.log("username的校驗結(jié)果"+isValid);
let errors:any = this.myFormGroup.get("username").errors;
console.log("username的錯誤信息是"+JSON.stringify(errors));
console.log(this.myFormGroup.value);
}
ngOnInit() {
}
}
4狭郑、將校驗器單獨放到一個文件中腹暖,然后用export的方式暴露出去
·1.在app目錄下新建一個文件夾
2.將剛剛定義的方法放置到validators.ts中
//引入文件
import { FormGroup,FormControl } from '@angular/forms';
// 注意:此時這兩個不再是一個TypeScript方法了,而是全局的一個函數(shù)
// 要用function來聲明
export function mobileValidator(control:FormControl):any {
// 手機(jī)號正則表達(dá)式
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的校驗結(jié)果是:"+valid);
return valid ? null : {mobile : true};
}
export function equalValidator(group:FormGroup):any {
let pwd:FormControl = group.get("pwd") as FormControl;
let pconfirm:FormControl = group.get("pconfirm") as FormControl;
let valid:boolean = (pwd.value === pconfirm.value);
console.log("密碼校驗結(jié)果:"+valid);
// 當(dāng)校驗通過時返回null,當(dāng)校驗不通過的時候返回{equal : true}
return valid ? null : {equal : true};
}
3.在組件中引入這兩個全局的方法
import { Component, OnInit} from '@angular/core';
import { FormGroup,FormControl,FormBuilder,Validators } from '@angular/forms';
//引入文件
import {mobileValidator,equalValidator} from '../validator/validators';
@Component({
selector: 'app-reactive-rigist',
templateUrl: './reactive-rigist.component.html',
styleUrls: ['./reactive-rigist.component.css']
})
export class ReactiveRigistComponent implements OnInit {
myFormGroup:FormGroup;
constructor(fb:FormBuilder) {
this.myFormGroup = fb.group({
username:['',[Validators.required,Validators.minLength(6)]],
//此次修改
mobile:['',mobileValidator],
passwordGroup:fb.group({
pwd:[''],
pconfirm:['']
// 此處修改
},{validator:equalValidator})
})
}
mySubmit(){
let isValid:boolean = this.myFormGroup.get("username").valid;
console.log("username的校驗結(jié)果"+isValid);
let errors:any = this.myFormGroup.get("username").errors;
console.log("username的錯誤信息是"+JSON.stringify(errors));
console.log(this.myFormGroup.value);
}
ngOnInit() {
}
}
4.結(jié)果是相同的
5翰萨、用.myFormGroup的valid屬性來判斷整個表單中所有的值是否是合法的
1.修改代碼
mySubmit(){
if(this.myFormGroup.valid) {
//只有合法時才打印模型信息
console.log(this.myFormGroup.value);
}else {
console.log("校驗未通過");
}
}
2.結(jié)果
6脏答、校驗不通過時,顯示錯誤信息給用戶
1.修改模版
<form [formGroup]="myFormGroup">
<p>用戶名:<input type="text" formControlName="username"></p>
<!-- 新增校驗信息 -->
<!-- 當(dāng)校驗不通過時返回true,所以取反 -->
<div [hidden]="!myFormGroup.hasError('required','username')">
用戶名是必填項
</div>
<div [hidden]="!myFormGroup.hasError('minlength','username')">
用戶名最小長度是6位
</div>
<p>手機(jī)號:<input type="text" formControlName="mobile"></p>
<div [hidden]="!myFormGroup.hasError('mymobile','mobile')">
請輸入正確的手機(jī)號
</div>
<div formGroupName="passwordGroup">
<p>密碼:<input type="password" formControlName="pwd"></p>
<p>確認(rèn)密碼:<input type="password" formControlName="pconfirm"></p>
</div>
<div [hidden]="!myFormGroup.hasError('myequal','passwordGroup')">
密碼輸入不一致
</div>
<button type="submit" (click)="mySubmit()">提交</button>
</form>
2.結(jié)果
7殖告、在檢驗器中寫錯誤信息
1.修改validators.ts
export function equalValidator(group:FormGroup):any {
let pwd:FormControl = group.get("pwd") as FormControl;
let pconfirm:FormControl = group.get("pconfirm") as FormControl;
let valid:boolean = (pwd.value === pconfirm.value);
console.log("密碼校驗結(jié)果:"+valid);
// return valid ? null : {myequal : true};
// 在此處添加錯誤信息
return valid ? null : {myequal : {errorInfo:"密碼輸入不一致"}};
}
2.修改模板
<div formGroupName="passwordGroup">
<p>密碼:<input type="password" formControlName="pwd"></p>
<!-- 在嵌套在formGroup內(nèi)的校驗阿蝶,要寫成數(shù)組['passwordGroup','pwd'] -->
<div [hidden]="!myFormGroup.hasError('minlength',['passwordGroup','pwd'])">
密碼最少6位
</div>
<p>確認(rèn)密碼:<input type="password" formControlName="pconfirm"></p>
</div>
<div [hidden]="!myFormGroup.hasError('myequal','passwordGroup')">
<!-- 此處修改為 -->
{{myFormGroup.getError('myequal','passwordGroup')?.errorInfo}}
</div>
3.結(jié)果相同
8、異步校驗器
將mobile檢驗器改為異步校驗器
1.修改validators.ts
import{ Observable } from "rxjs";
// 異步校驗器
export function mobileAsyncValidator(control:FormControl):any {
// 手機(jī)號正則表達(dá)式
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的校驗結(jié)果是:"+valid);
// 將返回值放到一個流里面返回
return Observable.of( valid ? null : {mymobile : true}).delay(5000);
}
2.修改reactive-rigist.component.ts
mobile:['',mobileValidator,mobileAsyncValidator]
3.修改模版
添加
<div>
{{myFormGroup.status}}
</div>
4.結(jié)果
5秒后
<5>狀態(tài)字段
包括:touched和untouched 黄绩、 pristine和dirty 羡洁、 pending
touched和untouched:
用來判斷用戶是否訪問過這個字段,也就是這個字段是否獲取過焦點爽丹。若獲取過焦點筑煮,則touched是true,untouched 是false粤蝎。
<p>用戶名:<input type="text" formControlName="username"></p>
<!-- 當(dāng)username通過校驗咆瘟,或者狀態(tài)是untouched時隱藏校驗信息 -->
<div [hidden]="myFormGroup.get('username').valid ||myFormGroup.get('username').untouched">
<div [hidden]="!myFormGroup.hasError('required','username')">
用戶名是必填項
</div>
<div [hidden]="!myFormGroup.hasError('minlength','username')">
用戶名最小長度是6位
</div>
</div>
pristine和dirty
如果一個字段的值從來沒被改變過,那么pristine為true诽里,dirty為false谤狡。
<!-- moblie通過校驗或者值從來沒被修改過卧檐,隱藏錯誤信息 -->
<div[hidden]="myFormGroup.get('mobile').valid ||myFormGroup.get('mobile').pristine">
<div [hidden]="!myFormGroup.hasError('mymobile','mobile')">
請輸入正確的手機(jī)號
</div>
</div>
pending
當(dāng)一個字段正處于異步檢驗時墓懂,pending為true
<div [hidden]="!myFormGroup.get('mobile').pending">
正在校驗手機(jī)號合法性
</div>
注意
針對所有的字段霉囚,angular會自動根據(jù)字段的狀態(tài)來為它添加一些樣式。
.myError {
border: 1px solid red;
}
<!-- 當(dāng)這個字段無效且狀態(tài)為touched時盈罐,增加myError類 -->
<p>用戶名:<input [class.myError]="myFormGroup.get('username').invalid && myFormGroup.get('username').touched" type="text" formControlName="username"></p>
<6>模版式表單校驗
1榜跌、生成兩個指令
指令可以被看成是一個沒有模版的component盅粪,指令是作為屬性來用的。
ng g directive directives/moblieValidator
ng g directive directives/equalValidator