Я понимаю вашу проблему. Если форма имеет много проверенных элементов управления, установка сообщений об ошибках в шаблоне может привести к путанице. Я предлагаю вам перенести все проверки ошибок в файл компонента. Проверьте этот Stackblitz, который я сделал: https://stackblitz.com/edit/angular-dugfod. Он основан на превосходном курсе Деборы Кураты о реактивных формах в Pluralsight (на момент написания этого ответа курс доступен бесплатно).
Основные моменты в примере Stackblitz - это :
1) Создайте массив сообщений об ошибках для каждого проверенного элемента управления в форме:
private validationMessages = [
{
controlName: 'name',
messages: { required: 'Name is required', minlength: 'Min length 3' },
message: '' // for the actual message to be shown in the form
},
{
controlName: 'country',
messages: { countryNot: "Country can't be England" },
message: ''
},
2) Создайте функцию, которая проверяет наличие ошибок в элементе управления и устанавливает соответствующее сообщение об ошибке. в массиве:
setMessage(controlName: string) {
let control = this.form.get(controlName);
const val = this.validationMessages.filter(x => x.controlName === controlName)[0];
val.message = '';
if (control.errors) {
val.message = Object.keys(control.errors)
.map(key => val.messages[key]).join(' ');
}
}
3) В методе ngOnInit
установите Observable
для отслеживания изменений проверенных элементов управления и для каждого изменения значения вызовите функцию setMessage
:
const fields = ['name', 'country', 'numberOfPlayers', 'coach', 'playerLimitsGroup.minPlayers',
'playerLimitsGroup.maxPlayers', 'playerLimitsGroup'];
fields.forEach(field => {
const control = this.form.get(field);
control.valueChanges.subscribe(
() => this.setMessage(field)
);
this.setMessage(field); // set the initial error messages for demonstration
});
4) Создать метод для получения текущего сообщения об ошибке элемента управления. Обратите внимание, что здесь вы можете решить, хотите ли вы показывать сообщения об ошибках всегда или только когда элемент управления загрязнен или затронут:
getMessage(controlName: string) {
let control = this.form.get(controlName);
let hideCleanErrors = this.form.get('hideCleanErrors').value;
if (control.dirty || control.touched || !hideCleanErrors) {
return this.validationMessages.filter(x => x.controlName === controlName)[0].message;
}
return '';
}
5) Теперь у вас есть аккуратный способ показать сообщения об ошибках для каждого элемента управления в шаблоне:
<label>Name:
<input type="text" formControlName="name">
</label>
<span>{{getMessage('name')}}</span>
Кроме того, мой пример Stackblitz показывает несколько способов настройки пользовательских валидаторов с параметрами и без параметров, межполевую валидацию и настройку валидатора во время выполнения.