У меня есть форма Form Builder в моем проекте Angular 6, и у меня возникает проблема с валидаторами.
Я думаю, что знаю, в чем проблема, но не знаю, как это исправить. У меня есть специальный валидатор (не совсем обычай, я использую min() и max() с настраиваемой переменной для проверки)
И, вероятно, форма инициализируется до этих значений.
Форма объявляется перед конструктором (я попытался переместить его в конструкцию и в ngOnInit, тот же результат)
myForm = this.fb.group({
title: [""],
date: [""],
max_score: [, [Validators.required, Validators.max(6), Validators.min(1)]],
min_score: [, [Validators.required, Validators.max(6), Validators.min(1)]]
});
constructor(private fb: FormBuilder) {}
Как и все работает, даже валидаторы. max_score
и min_score
- это два выпадающих min_score
, где вы можете выбрать номер.
Я хочу достичь этого:
max_score: [, [Validators.required, Validators.max(6), Validators.min(this.myForm.get("min_points").value)]],
min_score: [, [Validators.required, Validators.max(this.myForm.get("max_score").value), Validators.min(1)]]
Таким образом, max_score
не может быть ниже min_score
, а min_score
не может быть выше max_score
!
Но это дает мне ошибку:
TypeError: Cannot read property 'get' of undefined
Поэтому я предполагаю, что значение this.myForm.get("max_score").value
не доступно, когда инициализируется построитель форм.
Как я могу это решить? Эти значения являются необязательными в моей форме, поэтому исправьте, что они не имеют значения с самого начала, и я просто хочу установить проверку, которая позволяет избежать выбора min_value, которое больше, чем max_value
Я даже попытался поставить this.myForm.get.... в функцию:
getMaxPoints(): number {
if (this.myForm.get("max_score").value) {
return this.myForm.get("max_score").value;
} else return null;
}
а потом
min_score: [, [Validators.required, Validators.max(this.getMaxPoints()), Validators.min(1)]]
но я получаю ту же ошибку!
Какое обходное решение для этой проблемы?
Вы можете добавить (keyup)="checkMinMax()"
в свой html как на min, так и max. В функции checkMinMax вы можете проверить содержимое this.myForm.get("max_score").value
и this.myForm.get("min_score").value
либо отображает сообщение с * ngIf, как вы упомянули в своем комментарии или силу минимальное или максимальное значение должно быть одинаковым с другим, если пользовательский ввод превышает его. ( или оба).
Кроме того, делая это, вы можете просто использовать необходимый валидатор.
Когда вы создаете форму, вы передаете значения массиву validators, значения, которые передаются только во время создания.
Поэтому, если вы используете выражение типа
Validators.max(this.myForm.get("max_points").value)
вы оцениваете при создании формы. Таким myForm
переменная myForm
по-прежнему не определена.
Попробуйте использовать некоторые переменные вместо доступа к свойствам myForm
следующим образом:
minVal: number = 5;
maxVal: number = 5;
max_score: [, [Validators.required, Validators.max(6), Validators.min(minVal)]],
min_score: [, [Validators.required, Validators.max(maxVal), Validators.min(1)]]
Чтобы проверить данные, получающие некоторые параметры из формы, вы должны использовать дополнительные из this.fb.group()
Вы можете попробовать что-то вроде этого:
myForm = this.fb.group({
title: [""],
date: [""],
max_score: [, [Validators.required]],
min_score: [, [Validators.required]]
},
{
// THIS IS EXTRA!!!!!
validator: [customValidator()]
});
Это пример customValidator
:
export function customValidator() {
return (group: FormGroup) => {
const minScore = group.controls['min_score'],
maxScore = group.controls['max_core'],
minPoints = group.controls['min_points'];
if (/** some condition **/) {
return minPoints.setErrors({'notMatching': true});
} else {
return minPoints.setErrors(null);
}
};
}
Обратите внимание, что в customValidator
вы customValidator
доступ к данным myForm, myForm
доступным для его элементов управления.
Затем в вашем шаблоне вам нужно показать ошибки в зависимости от
<div *ngIf="f.min_points.errors && f.min_points.errors.notMatching">NOT VALID</div>
Я не помню, если доступна ошибка notMatching
, но вы можете распечатать все доступные ошибки с помощью
<pre>{{ f.min_points.errors | json }</pre>
где f
- метод удобного геттера, подобный этому:
get f() {
return this.myForm.controls;
}
так должно быть:
public myForm:FormGroup; // you should do this
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
title: [''],
date: [''],
max_score: ['', [Validators.required, Validators.max(6), Validators.min(1)]],
min_score: ['', [Validators.required, Validators.max(6), Validators.min(1)]]
});
}
и получить доступ к нему:
this.myForm.get("max_score").value
или же:
this.myForm.controls["max_score"].value
max_score
вместоthis.myForm.get("max_points").value)
же самое относится и кmin_points