Я правильно строю массив форм следующим образом:
this.items.forEach(element => {
(<FormArray>this.myFormFixtures.get('fixtures')).push(this.fBuilder.group({
id: [element.id],
name: [element.name, Validators.required],
description: [element.description],
startDateTime: this.buildTimeDetails(element.startDateTime),
venueId: [element.venueId, Validators.required],
participants: this.buildParticipants(element.participants)
}));
});
this.myFormFixtures.valueChanges
.subscribe(formData => this.checkFixturesFormValidity(formData));
Ключ «Участники» генерируется в виде массива с двумя идентификаторами с нулевым значением, например:
[
{id: null},
{id: null}
]
По умолчанию 2 идентификатора не являются обязательными. Но я хочу установить оба идентификатора участников formControlNames как обязательные при получении значения.
Пока моя функция "checkFixturesFormValidity" выглядит так, но по какой-то причине проверка не выполняется:
checkFixturesFormValidity(formData)
{
console.log(formData);
const control = <FormArray>this.myFormFixtures.controls['fixtures'];
for (let i = 0; i < control.length; i++) {
const participantsControl = (<FormArray>this.myFormFixtures.controls['fixtures']).at(i).get('participants') as FormArray;
if ((((<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(0).get('id').value) != null) || (((<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(1).get('id').value) != null))
{
(<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(0).get('id').setValidators([Validators.required]);
(<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(1).get('id').setValidators([Validators.required]);
}
}
}
1 ответ
Мне удалось несколько сократить все эти длинные пути свойств, поскольку в итерациях мы можем передавать, например, объект, который вы назвали в своем *ngFor
, так что в методах нам не нужно начинать с this.myFormFixtures.controls....
Итак, что мы сделали здесь, так это установили событие изменения для вашего выбора. Поскольку мы знаем, что когда пользователь делает выбор, если значение отличается от null
, мы устанавливаем Validators.required
.
Итак, содержимое tbody
будет выглядеть так (сокращенно):
<tr *ngFor="let fixture of myFormFixtures.controls.fixtures.controls;
let c=index" [formGroupName]="c">
<td><input type="text" formControlName="name" /></td>
<td class="teamColumn">
<div formArrayName="participants">
<div *ngFor="let thisParticipant of fixture.controls.participants.controls;
let i=index" [formGroupName]="i">
<!-- We pass the current formgroup and value of dropdown,
which is null, 1 or 2 -->
<select formControlName="id
(change)="doSomething(fixture.controls.participants,
thisParticipant.controls.id.value)">
<option [ngValue]=null>Please select</option>
<option [ngValue]="1">Team Red</option>
<option [ngValue]="2">Team Blue</option>
</select>
</div>
</div>
</td>
</tr>
Тогда doSomething()
будет выглядеть так:
// form array and chosen value
doSomething(formArr, val) {
for (let x of formArr.controls) {
x.controls.id.setValidators([Validators.required]);
x.controls.id.updateValueAndValidity();
}
}
Ваша демонстрация: https://plnkr.co/edit/hovobDwYUgH3C6fbe7eB?p=preview
PS, это не учитывается, если пользователь отменяет выбор значения.
subscribe
и вызовом метода :) Что касается вашего другого вопроса, вот одна возможность решить, что, если оба не отмечены, валидатор будет удален: < a href = "https://plnkr.co/edit/EFUMbA2oKgHn5aZUWfOT?p=preview" rel = "nofollow noreferrer"> plnkr.co/edit/EFUMbA2oKgHn5aZUWfOT?p=preview
Похожие вопросы
Новые вопросы
angular
Вопросы по Angular (не путать с AngularJS), веб-фреймворку от Google. Используйте этот тег для угловых вопросов, которые не относятся к конкретной версии. Для более старой веб-платформы AngularJS (1.x) используйте тег angularjs.
updateValueAndValidity()
. Если это не помогает, создайте плункер, демонстрирующий проблему..subscribe(formData => this.checkFixturesFormValidity(formData))
checkFixturesFormValidity()
вызывается каждый раз, когда что-то происходит в значениях формы, и, поскольку вы используетеupdateValueAndValidity()
в этом, "происходят изменения", что означает subscribe запускается снова, и так продолжается до тех пор, пока браузер не выйдет из строя;) Вместо этого вы должны рассмотреть простое событиеchange
для поля.updateValueAndValidity
решит вашу проблему. В качестве примечания, даже если это вопрос мнения, я стал полагаться на события вместо того, чтобы использоватьvalueChanges
, если у меня нет какой-либо конкретной причины. С событиями у вас есть более жесткий контроль над тем, что и когда запускать. При использовании valueChanges вы не можете контролировать его так жестко, и с точки зрения производительности это может стать тяжелым. Даже при инициализации компонентаvalueChanges
будет запускаться x количество раз, что обычно совершенно не нужно :)