表單驗證是前端開發中重要的而且常見的工做 好比下面的表單包含三個字段:html
咱們能夠藉助Angular的formControl來實現,這裏咱們基於FormControl建立一個子類ProductFormControl來提升可複用性前端
核心代碼: form.model.ts 該文件是表單模型文件,與業務無關。只包含一個收集表單錯誤信息的方法json
import { FormControl, FormGroup, Validators } from "@angular/forms";
// 自定義驗證器
import { LimitValidator } from "./limit.formvalidator";
export class ProductFormControl extends FormControl {
label: string;
modelProperty: string;
constructor(label:string, property:string, value: any, validator: any) {
super(value, validator);
this.label = label;
this.modelProperty = property;
}
// 此方法用於收集錯誤信息,而後在模板中遍歷輸出,
getValidationMessages() {
let messages: string[] = [];
if (this.errors) {
for (let errorName in this.errors) {
switch (errorName) {
case "required":
messages.push(`You must enter a ${this.label}`);
break;
case "minlength":
messages.push(`A ${this.label} must be at least
${this.errors['minlength'].requiredLength}
characters`);
break;
case "maxlength":
messages.push(`A ${this.label} must be no more than
${this.errors['maxlength'].requiredLength}
characters`);
break;
case "limit":
messages.push(`A ${this.label} cannot be more
than ${this.errors['limit'].limit}`);
break;
case "pattern":
messages.push(`The ${this.label} contains
illegal characters`);
break;
}
}
}
return messages;
}
}
// 業務相關,專門驗證 Product Form
// 注意 new ProductFormControl() 不是 new FormControl()
export class ProductFormGroup extends FormGroup {
constructor() {
super({
name: new ProductFormControl("Name", "name", "", Validators.required),
category: new ProductFormControl("Category", "category", "",
Validators.compose([Validators.required,
Validators.pattern("^[A-Za-z ]+$"),
Validators.minLength(3),
Validators.maxLength(10)])),
price: new ProductFormControl("Price", "price", "",
Validators.compose([Validators.required,
LimitValidator.Limit(100),
Validators.pattern("^[0-9\.]+$")]))
});
}
get productControls(): ProductFormControl[] {
return Object.keys(this.controls)
.map(k => this.controls[k] as ProductFormControl);
}
getFormValidationMessages(form: any) : string[] {
let messages: string[] = [];
this.productControls.forEach(c => c.getValidationMessages()
.forEach(m => messages.push(m)));
return messages;
}
}
複製代碼
其中 limit.formvalidator.ts 封裝了一個驗證長度限制的自定義驗證器bash
import { FormControl } from "@angular/forms";
export class LimitValidator {
static Limit(limit:number) {
return (control:FormControl) : {[key: string]: any} => {
let val = Number(control.value);
if (val != NaN && val > limit) {
return {"limit": {"limit": limit, "actualValue": val}};
} else {
return null;
}
}
}
}
複製代碼
最後在用到的組件中,直接引入 form.modelapp
import { Component } from "@angular/core";
import { NgForm } from "@angular/forms";
import { Product } from "./product.model";
import { ProductFormGroup } from "./form.model";
@Component({
selector: "app",
templateUrl: "template.html"
})
export class ProductComponent {
form: ProductFormGroup = new ProductFormGroup();
newProduct: Product = new Product();
get jsonProduct() {
return JSON.stringify(this.newProduct);
}
addProduct(p: Product) {
console.log("New Product: " + this.jsonProduct);
}
formSubmitted: boolean = false;
submitForm(form: NgForm) {
this.formSubmitted = true;
if (form.valid) {
this.addProduct(this.newProduct);
this.newProduct = new Product();
form.reset();
this.formSubmitted = false;
}
}
}
複製代碼
完整實例能夠參見: stackblitz.com/edit/angula…ui