Я пытаюсь внедрить собственный валидатор в общий класс валидатора. В основном я знаю об этом, чтобы написать обычный пользовательский валидатор в нагноенном классе, но здесь возникает небольшая путаница при записи в общий класс валидатора. Если кто-нибудь знает, пожалуйста, помогите мне.
Вот мой файл generic-validator.ts
import { FormGroup } from '@angular/forms';
// Generic validator for Reactive forms
// Implemented as a class, not a service, so it can retain state for multiple forms.
export class GenericValidator {
// Provide the set of valid validation messages
// Stucture:
// controlName1: {
// validationRuleName1: 'Validation Message.',
// validationRuleName2: 'Validation Message.'
// },
// controlName2: {
// validationRuleName1: 'Validation Message.',
// validationRuleName2: 'Validation Message.'
// }
constructor(private validationMessages: { [key: string]: { [key: string]: string } }) {
}
// Processes each control within a FormGroup
// And returns a set of validation messages to display
// Structure
// controlName1: 'Validation Message.',
// controlName2: 'Validation Message.'
processMessages(container: FormGroup): { [key: string]: string } {
let messages = {};
for (let controlKey in container.controls) {
if (container.controls.hasOwnProperty(controlKey)) {
let c = container.controls[controlKey];
// If it is a FormGroup, process its child controls.
if (c instanceof FormGroup) {
let childMessages = this.processMessages(c);
Object.assign(messages, childMessages);
} else {
// Only validate if there are validation messages for the control
if (this.validationMessages[controlKey]) {
messages[controlKey] = '';
if ((c.dirty || c.touched) &&
c.errors) {
for (let messageKey in c.errors) {
if (c.errors.hasOwnProperty(messageKey) &&
this.validationMessages[controlKey][messageKey]) {
messages[controlKey] += this.validationMessages[controlKey][messageKey];
}
}
}
}
}
}
}
return messages;
}
}Вот мои параметры для пользовательского валидатора например: '22, 3333,4,555,66 ', [2,5] первая - это строка, разделенная запятыми ... которая может содержать записи длиной 2 или 5 Здесь условие: каждая строка с запятой должна быть> 2.
@DeborahK Да, найди, большое тебе спасибо. Я следил за вашими видео с множественного числа на сайте, ваше объяснение фантастическое.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Когда я пишу собственные валидаторы, они обычно используются с реактивными формами. Мои пользовательские валидаторы находятся в классе, который расширяет валидаторы из модуля @ angular / forms. При этом вы возвращаете null, если проверка правильная, и объект, если она плохая. Следующие проверки проверяют наличие недопустимых символов.
import { FormControl, Validators, ValidatorFn } from '@angular/forms';
// setup simple regex for white listed characters
const validCharacters = /[^\s\w,.:&/()+%'`@-]/;
// create your class that extends the angular validator class
export class CustomValidators extends Validators {
// create a static method for your validation
static invalidateCharacters(control: FormControl) {
// first check if the control has a value
if (control.value && control.value.length > 0) {
// match the control value against the regular expression
const matches = control.value.match(invalidCharacters);
// if there are matches return an object, else return null.
return matches && matches.length ? { invalid_characters: matches } : null;
} else {
return null;
}
}
}
Создайте FormErrorService, который создает ваше сообщение об ошибке:
import { Injectable } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Injectable()
export class FormErrorService {
// return list of error messages
public validationMessages() {
const messages = {
required: 'This field is required',
email: 'This email address is invalid',
is1980OrLater: 'Please enter a date that is after 01/01/1980.',
maxDateFailed: (failText: string) => {
return failText;
},
minDateFailed: (failText: string) => {
return failText;
},
invalid_characters: (matches: any[]) => {
let matchedCharacters = matches;
matchedCharacters = matchedCharacters.reduce((characterString, character, index) => {
let string = characterString;
string += character;
if (matchedCharacters.length !== index + 1) {
string += ', ';
}
return string;
}, '');
return `These characters are not allowed: ${matchedCharacters}`;
},
};
return messages;
}
// Validate form instance
// check_dirty true will only emit errors if the field is touched
// check_dirty false will check all fields independent of
// being touched or not. Use this as the last check before submitting
public validateForm(formToValidate: FormGroup, formErrors: any, checkDirty?: boolean) {
const form = formToValidate;
for (const field in formErrors) {
if (field) {
formErrors[field] = '';
const control = form.get(field);
const messages = this.validationMessages();
if (control && !control.valid) {
if (!checkDirty || (control.dirty || control.touched)) {
for (const key in control.errors) {
if (key && key !== 'invalid_characters') {
formErrors[field] = formErrors[field] || messages[key];
} else {
formErrors[field] = formErrors[field] || messages[key](control.errors[key]);
}
}
}
}
}
}
return formErrors;
}
}
Где вы создаете форму в своем компоненте:
import {CustomValidators} from 'filepath';
import {FormErrorService} from 'formerrorservicepath';
myFormGroup: FormGroup;
public formErrors = {
myInput: ''
};
formErrors = [];
constructor(
public formErrorService: FormErrorService
) {}
// then in your ngOnInit
this.myFormGroup = new FormGroup({});
this.myFormGroup.addControl('myInput', new FormControl());
this.myFormGroup.get('myInput').setValidators(Validators.compose([CustomValidators.invalidCharacters]);
this.myFormGroup.valueChanges.subscribe(data => {
this.formErrors = [];
this.formErrors = this.formErrorService.validateForm(
this.myFormGroup,
this.formErrors,
true
);
})
Теперь в вашем HTML:
<form [formGroup] = "myFormGroup">
<div>
<input type = "text" formControlName = "myInput"/>
<p *ngFor = "let error of formErrors">
{{error}}
</p>
<button type = "button" [diabled] = "!myFormGroup.valid">Action Button</button>
</div>
</form>
Вы можете попробовать фреймворк под названием ts.validator.fluent. Проверка универсального объекта. Свободные правила.
https://github.com/VeritasSoftware/ts.validator
Пакет NPM:
https://www.npmjs.com/package/ts.validator.fluent
Также есть Приложение Angular 6 CLI для демонстрации фреймворка:
https://github.com/VeritasSoftware/ts-validator-app-angular6
Вот пример того, как ваши модели TypeScript могут быть проверены с помощью фреймворка:
/* Install npm package ts.validator.fluent and then import like below */
import { IValidator, Validator, ValidationResult } from 'ts.validator.fluent/dist';
/*TypeScript model*/
class Person {
Name: string;
}
/* Validation rules */
var validatePersonRules = (validator: IValidator<Person>) : ValidationResult => {
return validator
.NotEmpty(m => m.Name, "Name cannot be empty")
.ToResult();
};
/* Populate model */
var person = new Person();
person.Name = "John Doe";
/* Validate model */
/* Sync */
var validationResult = new Validator(person).Validate(validatePersonRules);
/* Async */
var validationResult = await new Validator(person).ValidateAsync(validatePersonRules);
Этот код выглядит знакомым! :-) Если вы посмотрите репозиторий github, содержащий этот код, вы увидите, что вы не добавляете здесь настраиваемый валидатор. Вместо этого вы добавляете его в отдельный файл (number.validator.ts - это настраиваемый валидатор в приведенном примере).