Angular 2+ 自定义表单验证破坏了表单方法
Angular 2+ Custom form validation breaks the form methods
我有一个表格:
public buildUserForm(user: User = null): void {
this.selectedUserForm = this.fb.group({
id: 0,
isActive: [true],
isSuperUser: [null],
firstName: ['', Validators.required],
lastName: ['', Validators.required],
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: ['', Validators.email],
address1: ['', Validators.maxLength(50)],
address2: ['', Validators.maxLength(50)],
city: ['', Validators.maxLength(30)],
stateProvince: ['', Validators.maxLength(30)],
postalCode: ['', Validators.maxLength(10)],
phoneNumber1: ['', Validators.maxLength(10)],
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 。
如何在不丢失自定义表单验证的情况下恢复表单。
如果您的验证器函数不是唯一的,则需要 return 一个错误。
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' 验证将失败,并显示一条消息,说明它不是唯一的。
我有一个表格:
public buildUserForm(user: User = null): void {
this.selectedUserForm = this.fb.group({
id: 0,
isActive: [true],
isSuperUser: [null],
firstName: ['', Validators.required],
lastName: ['', Validators.required],
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: ['', Validators.email],
address1: ['', Validators.maxLength(50)],
address2: ['', Validators.maxLength(50)],
city: ['', Validators.maxLength(30)],
stateProvince: ['', Validators.maxLength(30)],
postalCode: ['', Validators.maxLength(10)],
phoneNumber1: ['', Validators.maxLength(10)],
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 。 如何在不丢失自定义表单验证的情况下恢复表单。
如果您的验证器函数不是唯一的,则需要 return 一个错误。
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' 验证将失败,并显示一条消息,说明它不是唯一的。