我通过这种方式正确构建表单数组:
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));
&#34;参与者&#34; key生成一个数组,其中包含2个具有空值的ID,如下所示:
[
{id: null},
{id: null}
]
默认情况下,2个ID是可选的。但我想设置两个参与者ID formControlNames,如果获得一个值,则需要它。
到目前为止我的&#34; checkFixturesFormValidity&#34;函数看起来像这样,但由于某种原因,验证没有设置:
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]);
}
}
}
答案 0 :(得分:3)
我有点能够缩短所有这些长属性路径,因为在迭代中,我们可以传递您在*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,如果用户取消选择值,则不考虑这一点。