#angular #angular-reactive-forms
#angular #angular-reactive-forms
Вопрос:
Я должен найти, имеет ли один из моих formcontrols ошибку шаблона. Если у него есть ошибка шаблона, тогда я должен изменить значение этого formcontrol на null.
Я написал рекурсивный метод, который вызывает сам себя, чтобы проверить, имеет ли элемент управления формой ошибку шаблона, а затем он, наконец, возвращает true или false, но я хочу изменить значение этого formcontrol на null
Вот моя рекурсивная функция,
hasPatternError(form: AbstractControl, isRecursion = false): boolean {
if (!isRecursion) {
this.patternErrors = [];
}
if (form instanceof FormControl) {
return form.hasError('pattern') === true ?? null;
}
if (form instanceof FormArray) {
form?.controls?.forEach(e => {
this.hasAnyPatternError(e, true);
});
}
if (form instanceof FormGroup) {
Object.keys(form.controls).forEach(key => {
const error = this.hasAnyPatternError(form.get(key), true);
if (error === true) {
this.patternErrors.push(error);
}
});
return this.patternErrors.length > 0 ? true : false;
}
}
Это моя форма, прослушивающая событие изменения значения. В событии изменения я вызываю приведенный выше рекурсивный метод, чтобы определить, имеет ли какой-либо элемент управления формой ошибку шаблона, но застрял при изменении значения этого formcontrol на null.
Примечание: я хочу, чтобы метод (hasPatternError) возвращал объект (с ошибкой, преобразованной в null, и не ожидал, что форма изменится в реальном времени)
ngOnInit() {
this.myForm = this.fb.group({
name: [''],
address: this.fb.group({
street: [''],
zip: [''],
licenseNo: ['', [Validators.required, Validators.pattern(/^[a-z0-9]{10}$/i)]],
})
})
this.myForm.valueChanges.subscribe(
data => {
console.log(this.hasAnyPatternError(this.myForm))
}
);
}
Вот мой код на stackblitz
Комментарии:
1. Похоже, что самый простой способ решить эту проблему — иметь в вашем средстве проверки шаблонов массив, который хранит фактические элементы управления, соответствующие условию, и возвращает это. Затем вы можете просто перебрать этот массив элементов управления и выполнить для них setValue (null)?
2. @MikeOne Не могли бы вы показать мне, как использовать приведенный выше stackblitz?
3. Извините, в данный момент я нахожусь на мобильном телефоне.. ключ в том, что вы теряете ссылку на фактический элемент управления, который вы тестируете.
4. У меня сложная вложенная группа форм с массивом форм
5. Я понимаю, но, думаю, в конце концов, вам нужны только элементы управления. Ваша функция кажется немного непоследовательной). Он может возвращать массив или одно (логическое) значение (он также находит только одно, а затем возвращает. Хитрость в том, что как только вы найдете элемент управления с ошибкой, переместите сам элемент управления в массив и верните его..
Ответ №1:
У вас уже есть ссылка на form
элемент управления и элемент управления key
, когда вы нажимаете на ошибку.
Установите значение для элемента управления в это время.
- Поскольку вы делаете это с помощью рекурсии, кажется, что у него какое-то странное поведение, когда я играл с ним в вашем стекблите.
- Но я хотел подчеркнуть, что для этого в элементе управления есть
setValue
функция, просто нужно определить наилучший способ ее использования в вашей логике. - Возможно, даже потребуется изучить отмену поведения и т. Д., Чтобы предоставить пользователю время для завершения нажатия клавиш.
if (!form.controls[key]['controls'] amp;amp; error === true) {
setTimeout(()=>{
form.controls[key].setValue('');
},3000)
this.patternErrors.push(error);
}
Я добавил a setTimeout
, чтобы подождать 3 секунды, прежде чем снова установить значение ''
для имитации отмены… похоже, это работает, но это неправильное решение, просто иллюстрирует принцип, который вам нужно изучить, чтобы setValue
правильно использовать в вашей рекурсии.
STACKBLITZ
https://stackblitz.com/edit/ng-nested-formgroup-zet7ry?file=src/app/app.component.ts
Комментарии:
1. Спасибо за ваше время маршала. Я хочу, чтобы метод возвращал объект (с ошибкой, преобразованной в null, и не ожидал, что форма изменится в реальном времени). Поддержал ваш вопрос.
2. Извините, я, должно быть, неправильно понял второе предложение вашего сообщения.
Ответ №2:
Вместо того, чтобы возвращать логические значения, указывающие на ошибку шаблона, возвращайте элементы управления с ошибками шаблона.
findPatternErrors(formItem: AbstractControl): FormControl[] {
if (formItem instanceof FormControl) {
if (formItem.hasError('pattern')) {
return [formItem];
}
return [];
}
if (formItem instanceof FormArray) {
const patternErrors: FormControl[] = [];
formItem.controls?.forEach(arrayItem => {
const ctrls = this.findPatternErrors(arrayItem);
Array.prototype.push.apply(patternErrors, ctrls);
});
return patternErrors;
}
if (formItem instanceof FormGroup) {
const patternErrors: FormControl[] = [];
Object.keys(formItem.controls).forEach(key => {
const ctrls = this.findPatternErrors(formItem.get(key));
if (ctrls.length) {
Array.prototype.push.apply(patternErrors, ctrls);
}
});
return patternErrors;
}
}
https://stackblitz.com/edit/ng-nested-formgroup-fmhfcs?file=src/app/app.component.ts
Комментарии:
1. Я знаю, как собрать элемент управления формой, который имеет ошибку, но моя конечная цель — иметь объект, значение которого formcontrol преобразовано в null.
2. В вашем примере, как я могу использовать массив patternErrors, который возвращает ваш метод, чтобы делать то, что я хочу?
3.
patternErrors.forEach(ctrl => ctrl.reset());
4. О, да, круто. Как я об этом не знал? Спасибо, но зачем нам нужны номера строк 44 и 45 (вы нажимаете ctrl на patternErrors)? Потому что мы уже отправляем ctrl в строке с номером 55
5. Это основано на вашем коде. Разные
if
условия.