如何使用angular 8将对象的动态数组分配给formgroup
How to assign dynamic array of objects to formgroup using angular8
您好,我从 API 命中获得了对象数组,该对象数组必须分配给 formGroup。我试过使用 formGroup 绑定,但它检测到 true/false 值,但它没有给我更改的对象数组中的 true/false 值,而是只给我 true/false 并且我还有日期输入字段在另一个数组中,它也不会检测到 true/false 值或更改后的值。
如果我写的代码有误,请指正,帮助我写出高效的代码。
感谢帮助。
演示:DEMO
TS:
private settingsInfoForm() {
if (!this.agentDetailsList) {
// Add
this.agentSettingsInfoForm = this.FB.group({
agentToogles: this.FB.array(this.detailsToggle.map(x=> x.boolValue)),
restrictionsInfo:this.FB.array(this.Restrictions.map(x=>x.boolValue))
});
} else {
// Edit
if (this.agentDetailsList) {
this.detailsToggle = this.agentDetailsList
this.agentSettingsInfoForm = this.FB.group({
agentToogles: this.FB.array(this.detailsToggle.map(x=>x.boolValue)),
restrictionsInfo:this.FB.array(this.Restrictions.map(x=>x.boolValue))
})
}
this.agentSettingsInfoForm.valueChanges.subscribe(data => {
this.formEdit = true;
console.log('agentSettingsInfoForm', this.formEdit)
})
}
}
HTML:
<form [formGroup]= "agentSettingsInfoForm">
<div class="row row-cols-2" formGroupName="agentToogles">
<div class="col" *ngFor="let toggleValue of detailsToggle;let i = index">
<div class="custom-control custom-switch mb-3">
<input type="checkbox" [formControlName]="i" id="{{toggleValue.id}}" >
<label class="custom-control-label" for="{{toggleValue.id}}">{{toggleValue.label}}</label>
</div>
</div>
</div>
<div class="col-6 {{isReadOnly ? 'link-disabled' : ''}}"
*ngFor="let restrictValue of Restrictions;let i = index" formGroupName="restrictionsInfo">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="{{restrictValue.id}}"
[(ngModel)]="restrictValue.boolValue" [ngModelOptions]="{standalone: true}"
>
<label class="custom-control-label" for="{{restrictValue.id}}">{{restrictValue.label}}</label>
</div>
<div class="form-group">
<input type="text" class="form-control restrictionDate" id="{{restrictValue.id}}" placeholder="MM/DD/YYYY HH:MM AM/PM"
[disabled]="!restrictValue.boolValue" [(ngModel)]="restrictValue.datetime" (click)="dateRestriction($event, i)"
[ngModelOptions]="{standalone: true}" >
</div>
</div>
</form>
您在使用表单生成器时不使用 [(ngModel)]
。相反,您应该使用 formControlName
指令。当您使用表单生成器数组时,您还应该使用 formArrayName
指令。
此外,您需要传递一个控件数组而不是一个值数组来构建生成器。
我将根据您的代码创建一个简单示例,向您展示如何应用该技术。
如果您像这样在组件中设置表单:
component.ts
ngOnInit() {
this.values = ['', '', ''];
this.form = this.formBuilder.group({
values: this.formBuilder.array(
// this is an array of controls - NOT values
this.values.map(x => this.formBuilder.control(x))
)
});
}
您可以像这样使用 HTML 中的指令:
component.html
<form (submit)="onSubmit()">
<fieldset [formGroup]="form">
<div formArrayName="values">
<div *ngFor="let value of values;let i = index">
<input [formControlName]="i" />
</div>
</div>
<button>Submit</button>
</fieldset>
</form>
请注意我是如何使用 formArrayName
指令包装表单控件的,并将 formControlName
设置为数组索引。
演示:https://stackblitz.com/edit/angular-lbo6qn
数组中的多个表单控件
如果要为表单数组中的每个项目创建多个控件,则需要设置表单以反映这一点。为表单数组中的每个 属性 创建一个表单控件。
this.form = this.FB.group({
array: this.FB.array(
this.values.map(x => this.FB.group({
boolValue: this.FB.control(x.boolValue),
label: this.FB.control(x.label)
}))
)
});
您的 HTML 结构与您的表单结构匹配:
<form [formGroup]="form" (submit)="onSubmit()">
<div formArrayName="array">
<div *ngFor="let value of values;let i = index">
<div [formGroupName]="i">
<input type="checkbox" formControlName="boolValue" />
<input type="text" formControlName="label" />
</div>
</div>
</div>
<button>Save</button>
</form>
然后您可以在提交时访问更新后的值。同样,您的查询与声明的结构匹配。
onSubmit() {
this.form.get('array').value.forEach((formGroup: FormGroup, i: number) => {
this.values[i].boolValue = formGroup['boolValue'];
this.values[i].label = formGroup['label'];
});
}
此处的关键是 HTML 中的表单指令结构应与表单中的表单生成器组、数组和控件的结构相匹配。
分叉演示:https://stackblitz.com/edit/angular-xopwoz
这只是您如何应用该概念的示例,而不是针对您的问题的具体修复方法。您的问题使用日期字段和 jQuery。如何在 Angular 中创建日期选择器输入字段的问题既超出范围又在 Internet 上被广泛询问。将我的技术应用到您的代码库对您来说应该不是什么大问题。
您好,我从 API 命中获得了对象数组,该对象数组必须分配给 formGroup。我试过使用 formGroup 绑定,但它检测到 true/false 值,但它没有给我更改的对象数组中的 true/false 值,而是只给我 true/false 并且我还有日期输入字段在另一个数组中,它也不会检测到 true/false 值或更改后的值。 如果我写的代码有误,请指正,帮助我写出高效的代码。
感谢帮助。
演示:DEMO
TS:
private settingsInfoForm() {
if (!this.agentDetailsList) {
// Add
this.agentSettingsInfoForm = this.FB.group({
agentToogles: this.FB.array(this.detailsToggle.map(x=> x.boolValue)),
restrictionsInfo:this.FB.array(this.Restrictions.map(x=>x.boolValue))
});
} else {
// Edit
if (this.agentDetailsList) {
this.detailsToggle = this.agentDetailsList
this.agentSettingsInfoForm = this.FB.group({
agentToogles: this.FB.array(this.detailsToggle.map(x=>x.boolValue)),
restrictionsInfo:this.FB.array(this.Restrictions.map(x=>x.boolValue))
})
}
this.agentSettingsInfoForm.valueChanges.subscribe(data => {
this.formEdit = true;
console.log('agentSettingsInfoForm', this.formEdit)
})
}
}
HTML:
<form [formGroup]= "agentSettingsInfoForm">
<div class="row row-cols-2" formGroupName="agentToogles">
<div class="col" *ngFor="let toggleValue of detailsToggle;let i = index">
<div class="custom-control custom-switch mb-3">
<input type="checkbox" [formControlName]="i" id="{{toggleValue.id}}" >
<label class="custom-control-label" for="{{toggleValue.id}}">{{toggleValue.label}}</label>
</div>
</div>
</div>
<div class="col-6 {{isReadOnly ? 'link-disabled' : ''}}"
*ngFor="let restrictValue of Restrictions;let i = index" formGroupName="restrictionsInfo">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="{{restrictValue.id}}"
[(ngModel)]="restrictValue.boolValue" [ngModelOptions]="{standalone: true}"
>
<label class="custom-control-label" for="{{restrictValue.id}}">{{restrictValue.label}}</label>
</div>
<div class="form-group">
<input type="text" class="form-control restrictionDate" id="{{restrictValue.id}}" placeholder="MM/DD/YYYY HH:MM AM/PM"
[disabled]="!restrictValue.boolValue" [(ngModel)]="restrictValue.datetime" (click)="dateRestriction($event, i)"
[ngModelOptions]="{standalone: true}" >
</div>
</div>
</form>
您在使用表单生成器时不使用 [(ngModel)]
。相反,您应该使用 formControlName
指令。当您使用表单生成器数组时,您还应该使用 formArrayName
指令。
此外,您需要传递一个控件数组而不是一个值数组来构建生成器。
我将根据您的代码创建一个简单示例,向您展示如何应用该技术。
如果您像这样在组件中设置表单:
component.ts
ngOnInit() {
this.values = ['', '', ''];
this.form = this.formBuilder.group({
values: this.formBuilder.array(
// this is an array of controls - NOT values
this.values.map(x => this.formBuilder.control(x))
)
});
}
您可以像这样使用 HTML 中的指令:
component.html
<form (submit)="onSubmit()">
<fieldset [formGroup]="form">
<div formArrayName="values">
<div *ngFor="let value of values;let i = index">
<input [formControlName]="i" />
</div>
</div>
<button>Submit</button>
</fieldset>
</form>
请注意我是如何使用 formArrayName
指令包装表单控件的,并将 formControlName
设置为数组索引。
演示:https://stackblitz.com/edit/angular-lbo6qn
数组中的多个表单控件
如果要为表单数组中的每个项目创建多个控件,则需要设置表单以反映这一点。为表单数组中的每个 属性 创建一个表单控件。
this.form = this.FB.group({
array: this.FB.array(
this.values.map(x => this.FB.group({
boolValue: this.FB.control(x.boolValue),
label: this.FB.control(x.label)
}))
)
});
您的 HTML 结构与您的表单结构匹配:
<form [formGroup]="form" (submit)="onSubmit()">
<div formArrayName="array">
<div *ngFor="let value of values;let i = index">
<div [formGroupName]="i">
<input type="checkbox" formControlName="boolValue" />
<input type="text" formControlName="label" />
</div>
</div>
</div>
<button>Save</button>
</form>
然后您可以在提交时访问更新后的值。同样,您的查询与声明的结构匹配。
onSubmit() {
this.form.get('array').value.forEach((formGroup: FormGroup, i: number) => {
this.values[i].boolValue = formGroup['boolValue'];
this.values[i].label = formGroup['label'];
});
}
此处的关键是 HTML 中的表单指令结构应与表单中的表单生成器组、数组和控件的结构相匹配。
分叉演示:https://stackblitz.com/edit/angular-xopwoz
这只是您如何应用该概念的示例,而不是针对您的问题的具体修复方法。您的问题使用日期字段和 jQuery。如何在 Angular 中创建日期选择器输入字段的问题既超出范围又在 Internet 上被广泛询问。将我的技术应用到您的代码库对您来说应该不是什么大问题。