美文网首页
Angular 表单3--响应式表单 复杂验证

Angular 表单3--响应式表单 复杂验证

作者: 飞凡的陀螺 | 来源:发表于2019-05-18 17:11 被阅读0次

表单验证是前端开发中重要的并且常见的工作
比如下面的表单包含三个字段:

  • 验证要求:
    name: 必填
    Category: 必填,只能输入大小写,字符长度3到10
    Price:必填,只能输入不超过100的数字
  • 显示要求:
    错误在表单上放统一显示
image.png

我们可以借助Angular的formControl来实现,这里我们基于FormControl创建一个子类ProductFormControl来提高可复用性

核心代码:
form.model.ts
该文件是表单模型文件,与业务无关。只包含一个收集表单错误信息的方法

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 封装了一个验证长度限制的自定义验证器

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.model

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;
        }
    }
}

完整实例可以参见:
https://stackblitz.com/edit/angular-advance-form-control

相关文章

  • Angular 表单3--响应式表单 复杂验证

    表单验证是前端开发中重要的并且常见的工作比如下面的表单包含三个字段: 验证要求:name: 必填Category:...

  • Angular表单验证

    angular4里一个响应式编程的小例子 Angular2 响应式表单验证 Angular开发(十一)-关于响应式...

  • 细说 Angular 2+ 的表单(二):响应式表单

    细说 Angular 2+ 的表单(一):模板驱动型表单 响应式表单 响应式表单乍一看还是很像模板驱动型表单的,但...

  • Angular 表单1--响应式表单

    Angular 提供了两种不同的方法来通过表单处理用户输入:响应式表单和模板驱动表单。本节先讲响应式表单。最终实例...

  • ng-alain表单使用方式

    Angular表单 Angular提供两种不同的架构范式表单:模板驱动和响应式表单,官网也简单实现了动态表单范例。...

  • Angular表单处理

    第七章 表单处理 学习内容: 一.简述模板式表单与响应式表单的不同 Angular表单API 模板式表单简述: ...

  • 14.《Angular响应式表单》

    一、使用响应式表单 Angular 的响应式表单能让实现响应式编程风格更容易,这种编程风格更倾向于在非 UI 的数...

  • angular-表单验证

    angular已经集成了完善的表单验证体系,可以直接引入使用即可,十分方便。表单分为两种,一种是响应式表单,一种是...

  • angular 表单

    官网总结 链接地址:angular 表单github例子:github例子 1. 响应式表单和模板驱动表单 1.1...

  • Angular框架中FormArray中嵌套FormGroup

    Angular中FormGroup是用来管理一组表单控件的,响应式表单使用FormArray来动态的管理表单控件,...

网友评论

      本文标题:Angular 表单3--响应式表单 复杂验证

      本文链接:https://www.haomeiwen.com/subject/pabtzqtx.html