如何在 Angular 响应式表单中正确呈现动态表单?
How to render dynamic forms properly in Angular Reactive Forms?
我有一个 API 请求 returns JSON 数组,如下所示:
{
"address": {
"addressLine1": "499 Linden Boulevard",
"addressLine2": "Apt 4b",
"city": "Moraida",
"province": "Kansas",
"postalCode": "21763",
"country": "USA"
},
"phones": [
{
"phoneNumber": "+1 (887) 502-2245",
"phoneType": 3
},
{
"phoneNumber": "+1 (823) 536-7452",
"phoneType": 1
}
],
"email": "latti.sh@hotmail.com"
}
“phones”JSON 数组是动态的.. 意味着它可能有一个或多个项目或 none..
我正在尝试使用 Dynamic Reactive Forms,所以我定义了我的表单组,如下所示
addressInfoForm = new FormGroup({
addressLine1: new FormControl('', [Validators.required]),
addressLine2: new FormControl('', []),
city: new FormControl('', [Validators.required]),
province: new FormControl('', []),
postalCode: new FormControl('', [Validators.required]),
country: new FormControl({ value: '', disabled: true }, [Validators.required]),
email: new FormControl('', [Validators.email]),
phones: this.fb.array([this.fb.control('')]),
});
当我在 onInit()
方法中得到 JSON 响应时,我将表单值设置如下:
this.addressInfoForm.setValue({
addressLine1: this.clientIdentInfo.address.addressLine1,
addressLine2: this.clientIdentInfo.address.addressLine2,
city: this.clientIdentInfo.address.city,
province: this.clientIdentInfo.address.province,
postalCode: this.clientIdentInfo.address.postalCode,
country: this.clientIdentInfo.address.country,
email: this.clientIdentInfo.email,
// how to set the phones
});
我确实像这样构建了 get phones() 和 AddPhone() 方法。
get phones() {
return this.addressInfoForm.get('phones') as FormArray;
}
AddPhone() {
this.phones.push(this.fb.control(''));
this.phones.push(this.fb.control(''));
}
在我的 html 中,我正在尝试填充 phone 并能够通过 AddPhone()
方法添加新的 phone,如下所示:
<form *ngFor="let phone of phones.controls; let i=index;"
[formGroupName]="i"
formArrayName="phones">
<mat-grid-list cols="4" rowHeight="90px" gutterSize="10px">
<mat-grid-tile [colspan]="1">
<mat-form-field appearance="outline" class="form-field">
<mat-label>Phone {{i + 1}}</mat-label>
<input matInput class="input-field" formControlName="phoneNumber">
<mat-icon matSuffix>local_phone</mat-icon>
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field appearance="outline" class="form-field">
<mat-label>Phone Type</mat-label>
<mat-select formControlName="phoneType">
<mat-option *ngFor="let type of phoneTypes" [value]="type.phoneTypeId">
{{ type.phoneTypeName }}
</mat-option>
</mat-select>
</mat-form-field>
</mat-grid-tile>
</mat-grid-list>
</form>
不幸的是,这不起作用!有人可以帮助我以正确的方式实现这一目标吗?
您需要根据您的结果将 phone 控件添加到 phone 数组,并将值修补到 phones 格式数组。
this.addressInfoForm.patchValue({
addressLine1: result.address.addressLine1,
addressLine2: result.address.addressLine1,
city: result.address.city,
province: result.address.province,
postalCode: result.address.postalCode,
country: result.address.country,
email: result.email
});
for (let i = 0; i < result.phones.length - 1; i++) {
this.AddPhone();
}
result.phones.forEach((item, index) => {
this.phones.get(index.toString()).patchValue({
phoneNumber: item.phoneNumber,
phoneType: item.phoneType
});
});
这是您的解决方案的 stackblitz 示例:
https://stackblitz.com/edit/angular-ivy-bhclwz?file=src/app/app.component.ts
我有一个 API 请求 returns JSON 数组,如下所示:
{
"address": {
"addressLine1": "499 Linden Boulevard",
"addressLine2": "Apt 4b",
"city": "Moraida",
"province": "Kansas",
"postalCode": "21763",
"country": "USA"
},
"phones": [
{
"phoneNumber": "+1 (887) 502-2245",
"phoneType": 3
},
{
"phoneNumber": "+1 (823) 536-7452",
"phoneType": 1
}
],
"email": "latti.sh@hotmail.com"
}
“phones”JSON 数组是动态的.. 意味着它可能有一个或多个项目或 none.. 我正在尝试使用 Dynamic Reactive Forms,所以我定义了我的表单组,如下所示
addressInfoForm = new FormGroup({
addressLine1: new FormControl('', [Validators.required]),
addressLine2: new FormControl('', []),
city: new FormControl('', [Validators.required]),
province: new FormControl('', []),
postalCode: new FormControl('', [Validators.required]),
country: new FormControl({ value: '', disabled: true }, [Validators.required]),
email: new FormControl('', [Validators.email]),
phones: this.fb.array([this.fb.control('')]),
});
当我在 onInit()
方法中得到 JSON 响应时,我将表单值设置如下:
this.addressInfoForm.setValue({
addressLine1: this.clientIdentInfo.address.addressLine1,
addressLine2: this.clientIdentInfo.address.addressLine2,
city: this.clientIdentInfo.address.city,
province: this.clientIdentInfo.address.province,
postalCode: this.clientIdentInfo.address.postalCode,
country: this.clientIdentInfo.address.country,
email: this.clientIdentInfo.email,
// how to set the phones
});
我确实像这样构建了 get phones() 和 AddPhone() 方法。
get phones() {
return this.addressInfoForm.get('phones') as FormArray;
}
AddPhone() {
this.phones.push(this.fb.control(''));
this.phones.push(this.fb.control(''));
}
在我的 html 中,我正在尝试填充 phone 并能够通过 AddPhone()
方法添加新的 phone,如下所示:
<form *ngFor="let phone of phones.controls; let i=index;"
[formGroupName]="i"
formArrayName="phones">
<mat-grid-list cols="4" rowHeight="90px" gutterSize="10px">
<mat-grid-tile [colspan]="1">
<mat-form-field appearance="outline" class="form-field">
<mat-label>Phone {{i + 1}}</mat-label>
<input matInput class="input-field" formControlName="phoneNumber">
<mat-icon matSuffix>local_phone</mat-icon>
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field appearance="outline" class="form-field">
<mat-label>Phone Type</mat-label>
<mat-select formControlName="phoneType">
<mat-option *ngFor="let type of phoneTypes" [value]="type.phoneTypeId">
{{ type.phoneTypeName }}
</mat-option>
</mat-select>
</mat-form-field>
</mat-grid-tile>
</mat-grid-list>
</form>
不幸的是,这不起作用!有人可以帮助我以正确的方式实现这一目标吗?
您需要根据您的结果将 phone 控件添加到 phone 数组,并将值修补到 phones 格式数组。
this.addressInfoForm.patchValue({
addressLine1: result.address.addressLine1,
addressLine2: result.address.addressLine1,
city: result.address.city,
province: result.address.province,
postalCode: result.address.postalCode,
country: result.address.country,
email: result.email
});
for (let i = 0; i < result.phones.length - 1; i++) {
this.AddPhone();
}
result.phones.forEach((item, index) => {
this.phones.get(index.toString()).patchValue({
phoneNumber: item.phoneNumber,
phoneType: item.phoneType
});
});
这是您的解决方案的 stackblitz 示例: https://stackblitz.com/edit/angular-ivy-bhclwz?file=src/app/app.component.ts