另请参阅此处的示例。评论很好,所以很容易理解希望。
https://stackblitz.com/edit/angular-reactive-form-sobsoft
所以这就是我们需要维护 app.component.ts 中的动态字段
ngOnInit () {
// expan our form, create form array this._fb.array
this.exampleForm = this._fb.group({
companyName: ['', [Validators.required,
Validators.maxLength(25)]],
countryName: [''],
city: [''],
zipCode: [''],
street: [''],
units: this._fb.array([
this.getUnit()
])
});
}
/**
* Create form unit
*/
private getUnit() {
const numberPatern = '^[0-9.,]+$';
return this._fb.group({
unitName: ['', Validators.required],
qty: [1, [Validators.required, Validators.pattern(numberPatern)]],
unitPrice: ['', [Validators.required, Validators.pattern(numberPatern)]],
unitTotalPrice: [{value: '', disabled: true}]
});
}
/**
* Add new unit row into form
*/
private addUnit() {
const control = <FormArray>this.exampleForm.controls['units'];
control.push(this.getUnit());
}
/**
* Remove unit row from form on click delete button
*/
private removeUnit(i: number) {
const control = <FormArray>this.exampleForm.controls['units'];
control.removeAt(i);
}
现在在 HTML 中:
<!-- Page form start -->
<form [formGroup]="exampleForm" novalidate >
<div fxLayout="row" fxLayout.xs="column" fxLayoutWrap fxLayoutGap="3.5%" fxLayoutAlign="left" >
<!-- Comapny name input field -->
<mat-form-field class="example-full-width" fxFlex="75%">
<input matInput placeholder="Company name" formControlName="companyName" required>
<!-- input field hint -->
<mat-hint align="end">
Can contain only characters. Maximum {{exampleForm.controls.companyName.value.length}}/25
</mat-hint>
<!-- input field error -->
<mat-error *ngIf="exampleForm.controls.companyName.invalid">
This field is required and maximmum alowed charactes are 25
</mat-error>
</mat-form-field>
<!-- Country input field -->
<mat-form-field class="example-full-width" >
<input matInput placeholder="Country" formControlName="countryName">
<mat-hint align="end">Your IP country name loaded from freegeoip.net</mat-hint>
</mat-form-field>
</div>
<div fxLayout="row" fxLayout.xs="column" fxLayoutWrap fxLayoutGap="3.5%" fxLayoutAlign="center" layout-margin>
<!-- Street input field -->
<mat-form-field class="example-full-width">
<input matInput placeholder="Street" fxFlex="75%" formControlName="street">
</mat-form-field>
<!-- City input field -->
<mat-form-field class="example-full-width" >
<input matInput placeholder="City" formControlName="city">
<mat-hint align="end">City name loaded from freegeoip.net</mat-hint>
</mat-form-field>
<!-- Zip code input field -->
<mat-form-field class="example-full-width" fxFlex="20%">
<input matInput placeholder="Zip" formControlName="zipCode">
<mat-hint align="end">Zip loaded from freegeoip.net</mat-hint>
</mat-form-field>
</div>
<br>
<!-- Start form units array with first row must and dynamically add more -->
<mat-card formArrayName="units">
<mat-card-title>Units</mat-card-title>
<mat-divider></mat-divider>
<!-- loop throught units -->
<div *ngFor="let unit of exampleForm.controls.units.controls; let i=index">
<!-- row divider show for every nex row exclude if first row -->
<mat-divider *ngIf="exampleForm.controls.units.controls.length > 1 && i > 0" ></mat-divider><br>
<!-- group name in this case row index -->
<div [formGroupName]="i">
<div fxLayout="row" fxLayout.xs="column" fxLayoutWrap fxLayoutGap="3.5%" fxLayoutAlign="center">
<!-- unit name input field -->
<mat-form-field fxFlex="30%">
<input matInput placeholder="Unit name" formControlName="unitName" required>
</mat-form-field>
<!-- unit quantity input field -->
<mat-form-field fxFlex="10%">
<input matInput placeholder="Quantity" type="number" formControlName="qty" required>
</mat-form-field>
<!-- unit price input field -->
<mat-form-field fxFlex="20%">
<input matInput placeholder="Unit price" type="number" formControlName="unitPrice" required>
</mat-form-field>
<!-- unit total price input field, calculated and not editable -->
<mat-form-field >
<input matInput placeholder="Total sum" formControlName="unitTotalPrice">
</mat-form-field>
<!-- row delete button, hidden if there is just one row -->
<button mat-mini-fab color="warn"
*ngIf="exampleForm.controls.units.controls.length > 1" (click)="removeUnit(i)">
<mat-icon>delete forever</mat-icon>
</button>
</div>
</div>
</div>
<!-- New unit button -->
<mat-divider></mat-divider>
<mat-card-actions>
<button mat-raised-button (click)="addUnit()">
<mat-icon>add box</mat-icon>
Add new unit
</button>
</mat-card-actions>
</mat-card> <!-- End form units array -->
</form> <!-- Page form end -->