Assume that we have a FormGroup
called myForm
and it hold another FormGroups
called addresses
(since one person can have more than one address). Each address
have addressKind
to determine its kind.
In the class code, it should be like this
public myForm: FormGroup;
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.myForm = this.formBuilder.group({
addresses: this.formBuilder.array([this.initAddress()])
});
}
initAddress() {
return this.formBuilder.group({
"addressKind": ["", Validators.required]
});
}
In the template code, we loop throught the array of addresses
and assign its control addressKind
to a input
<div [formGroup]="myForm">
<div formArrayName="addresses">
<div *ngFor="let address of myForm.controls.addresses.controls; let i = index">
<mat-form-field>
<input matInput [formControl]="address.get('addressKind')" />
</mat-form-field>
</div>
</div>
</div>
We can also access address
via [formGroupName]
using index, and its control addressKind
via formControlName
in template code
<div *ngFor="let address of myForm.controls.addresses.controls; let i = index">
<mat-form-field [formGroupName]="i">
<input matInput formControlName="addressKind" />
</mat-form-field>
</div>
It sorter and more readable than the first way.
There is another way using get funcion in class code, we can add a get function for addresses
get addresses() {
return this.myForm.get('addresses') as FormArray;
}
Then access it directly in the template code
<mat-form-field>
<input matInput [formControl]="addresses.controls[i].get('addressKind')" />
</mat-form-field>
But in my opinion, I do not like this one