Angular 2+ 自定义表单验证打破了表单方法

问题描述

我有一个表格:

public buildUserForm(user: User = null): void {
    this.selectedUserForm = this.fb.group({
      id: 0,isActive: [true],isSuperUser: [null],firstName: ['',Validators.required],lastName: ['',username: ['',[Validators.required,UniqueNameValidator(this.userNamesList,user)]],password: ['',Validators.pattern('^(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])(?=\\D*\\d)[A-Za-z\\d!$%@#£€*?&]{8,}$')],emailAddress: ['',Validators.email],businessEmailAddress: ['',address1: ['',Validators.maxLength(50)],address2: ['',city: ['',Validators.maxLength(30)],stateProvince: ['',postalCode: ['',Validators.maxLength(10)],phoneNumber1: ['',employeeId: [''],notes: ['']
    });
    this.onFormChanges();
  }

自定义表单验证器:

import { Directive } from '@angular/core';
import { AbstractControl,ValidationErrors,ValidatorFn } from '@angular/forms';

Directive({
  selector: '[uniqueName]'
});

export function UniqueNameValidator(array: any[],exception = null): ValidatorFn {
  const valObject = { nameDuplicate: true }
  return (control: AbstractControl): ValidationErrors | null => {
    if (exception) {
      if (control.value === exception.name || control.value === exception.username) {
        return array.findindex(item => item.name === control.value || item.username === control.value) > 0 ? valObject : null;
      } else {
        return array.findindex(item => item.name === control.value || item.username === control.value) > 0 ? valObject : null;
      }
    } else {
      return array.findindex(item => item.name === control.value || item.username === control.value) > 0 ? valObject : null;
    }
  };
}

验证器工作并给我正确的消息。但是像 this.selectedUserForm.touched 或 this.selectedUserForm.valid 这样的方法不再起作用并且现在总是显示 False 。 如何在不丢失自定义表单验证的情况下恢复表单。

解决方法

如果验证器函数不唯一,则需要返回错误。

uniqueValidation(list: string[]): ValidatorFn {
    return (c: AbstractControl): { [key: string]: boolean } | null => {  
      if (c.value === null || c.pristine || c.value === '') {
        return null;
      } else if (c.dirty) {
        return (list.find(x => x === c.value)) ? { 'notunique': true } : null;
      }
      return null;
    }
  }

用法:

selectedUserForm: FormGroup;
  userNamesList: string[] = ['name1','name2']

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.buildForm();
  }

  uniqueValidation(list: string[]): ValidatorFn {
    return (c: AbstractControl): { [key: string]: boolean } | null => {  
      if (c.value === null || c.pristine || c.value === '') {
        return null;
      } else if (c.dirty) {
        return (list.find(x => x === c.value)) ? { 'notunique': true } : null;
      }
      return null;
    }
  }

  buildForm() {
    this.selectedUserForm = this.fb.group({
      userName: [null,[Validators.required,this.uniqueValidation(this.userNamesList)]]
    });
  }

演示:https://stackblitz.com/edit/angular-unique-validator-akeje2?file=src%2Fapp%2Fapp.component.ts

在此演示中,输入“name1”或“name2”,验证将失败并显示一条消息,表明它不是唯一的。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...