Angular 2 - 稍后在反应式数组中设置验证

时间:2017-07-29 18:26:41

标签: angular typescript

我通过这种方式正确构建表单数组:

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]);
                }


        }

    }

1 个答案:

答案 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,如果用户取消选择值,则不考虑这一点。