angular表单校验-模板驱动表单校验

来源:互联网 发布:海康威视端口未生效 编辑:程序博客网 时间:2024/05/29 16:37

本文仅仅是作为自己的笔记,因此没有详细解释,建议查看大神博客:https://www.pocketdigi.com/20170208/1561.html

模板

<form id="login-form" class="login-from" #registerForm="ngForm" (ngSubmit)="doSubmit(registerForm.value)">        <mat-form-field>          <input matInput placeholder="邮箱" id="email" name="email" [(ngModel)]="formData.email" required pattern="[\w]+?@[\w]+?\.[a-z]+?">          <mat-error *ngIf="formErrors.email">{{ formErrors.email }}</mat-error>        </mat-form-field>        <fieldset ngModelGroup="passwordGroup" #passwordGroup="ngModelGroup" aria-required="true">          <mat-form-field>            <input matInput placeholder="密码" type="password" id="password" name="password" [(ngModel)]="formData.password" #password="ngModel"  required minlength="8">            <!-- <mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility' : 'visibility_off'}}</mat-icon> -->          </mat-form-field>          <mat-form-field>            <!--使用自定义的校验器,加入repeatPassword指令,传入第一个密码输入框的ngModel,即用#password1="ngModel"声明的password1-->            <input matInput placeholder="确认密码" type="password" id="passwordConfirm" name="passwordConfirm" [(ngModel)]="formData.passwordConfirm" [repeatPassword]="password" >            <!-- <mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility' : 'visibility_off'}}</mat-icon> -->            <mat-error *ngIf="formErrors['passwordGroup.passwordConfirm']">{{ formErrors['passwordGroup.passwordConfirm'] }}</mat-error>          </mat-form-field>        </fieldset>        <button class="w-100p" mat-raised-button [disabled] = "!registerForm.valid" >注册</button>      </form>

组件

import { Component, OnInit ,ViewChild, AfterViewInit } from '@angular/core';import {NgForm} from "@angular/forms";import { Router } from '@angular/router';@Component({  selector: 'app-register',  templateUrl: './register.component.html',  styleUrls: ['./register.component.css']})export class RegisterComponent implements OnInit {  ngAfterViewInit(): void {    //订阅表单值改变事件    this.registerForm.valueChanges.subscribe(data => this.onValueChanged(data));  }  //找到表单  @ViewChild('registerForm') registerForm: NgForm;  formData = {} as any;  doSubmit(obj: any) {    //表单提交    console.log(JSON.stringify(obj));  }  onValueChanged(data) {    for (const field in this.formErrors) {      this.formErrors[field] = '';      //取到表单字段      const control = this.registerForm.form.get(field);      //表单字段已修改或无效      if (control && control.dirty && !control.valid) {        //取出对应字段可能的错误信息        const messages = this.validationMessages[field];        //从errors里取出错误类型,再拼上该错误对应的信息        for (const key in control.errors) {          this.formErrors[field] += messages[key] + '';        }      }    }  }  //存储错误信息  formErrors = {    'email': '',    'passwordGroup.password':'',    'passwordGroup.passwordConfirm':''  };  //错误对应的提示  validationMessages = {    'email': {      'required': '邮箱必须填写.',      'pattern': '邮箱格式不对',    },    'passwordGroup.password':{      'required': '请输入密码',      'minlength': '密码太短',    },    'passwordGroup.passwordConfirm':{      'required': '请重复输入密码',      'minlength': '密码太短',      'passwordNEQ':'两次输入密码不同',      'passwordInValid':''    },  };  constructor(private router : Router) { }  ngOnInit() {  }  gotoLogin(){    this.router.navigate(['user/login']);  }  recoverPwd(){    this.router.navigate(['/user/recover/pwd']);  }}

自定义校验器:repeat-password

import {Directive, Input, OnChanges, SimpleChanges} from '@angular/core';import {NG_VALIDATORS, FormControl, Validator, AbstractControl, ValidatorFn, NgModel} from "@angular/forms";@Directive({  selector: '[repeatPassword]',  providers: [{provide: NG_VALIDATORS, useExisting: RepeatPasswordDirective, multi: true}]})export class RepeatPasswordDirective implements Validator,OnChanges {  /**   * 校验方法   * @param c   * @returns {{[p: string]: any}}   */  validate(c: AbstractControl): {[p: string]: any} {    return verifyPassword(c,this.repeatPassword.control);  }  ngOnChanges(changes: SimpleChanges): void {      this.repeatPassword=changes['repeatPassword'].currentValue;  }  /**   * 通过属性传入另一个input标签的model   * 名称与选择器一致,就不需要在使用的时候加额外的属性传入   */  @Input() repeatPassword:NgModel;  constructor() { }}/** * 导出校验方法,供响应式表单使用 * @param passwordController * @returns {(currentControl:AbstractControl)=>{[p: string]: any}} */export function repeatPassword(passwordController:FormControl):ValidatorFn {  return (currentControl: AbstractControl): {[key: string]: any} => {    return verifyPassword(currentControl,passwordController);  };}function verifyPassword(currentControl: AbstractControl,passwordController:FormControl):{[key: string]: any} {    if(!passwordController.valid) {      console.log("密码1无效");      return {passwordInValid:{'errorMsg':''}}    }    if((!currentControl.untouched||currentControl.dirty)&&passwordController.value!=currentControl.value) {      return {passwordNEQ:{'errorMsg':'两次密码输入不一致!'}}    }}

注意:
这里写图片描述

出现上图错误是因为创建指令时使用:ng g directive repeatPassword
命令,自动添加了前缀app

@Directive({  selector: '[appRepeatPassword]',  providers: [{provide: NG_VALIDATORS, useExisting: RepeatPasswordDirective, multi: true}]})

改为repeatPassword即可
这里写图片描述

出现上图错误是由于
<input matInput placeholder="密码" type="password" id="password" name="password" [(ngModel)]="formData.password" #password1="ngModel" required minlength="8">

使用的字段是password,(不知道怎么描述)却是#password1。

改为#password即可

再次向大神致谢:https://www.pocketdigi.com/20170208/1561.html

原创粉丝点击