angular - 将 FormArray 与来自响应和 mat-checkbox 的对象一起使用
问题描述
完全消化了 Angular Reactive forms 文档后,我仍在努力实现以下功能:
使用我的 NgRx 商店中的分区列表,在 Angular 反应形式中为每个分区名称输出一个 mat-checkbox 并检查状态(使用 division.current 属性 - 以便默认检查当前活动的分区)。
这是我所在的位置:
新赛季组件.ts
export class NewSeasonComponent implements OnInit {
chooseDivisions: FormGroup;
divisions: FormArray;
allDivisions: Division[];
constructor(
private fb: FormBuilder,
private store: Store<AppState>
) {
}
ngOnInit() {
this.store.dispatch(new AllDivisionsRequested());
this.store
.pipe(
select(selectAllDivisions)
).subscribe(divisions => this.allDivisions = divisions);
this.chooseDivisions = this.fb.group({
divisions: this.fb.array([])
});
this.addDivisions();
}
createDivisionFormControl(division: Division): FormGroup {
return this.fb.group({
id: division.id,
name: division.name,
current: division.current
});
}
addDivisions(): void {
this.divisions = this.chooseDivisions.get('divisions') as FormArray;
this.allDivisions.map(
division => {
this.createDivisionFormControl(division);
}
);
}
总之 - 从商店中获取部门,创建一个包含空 formArray 的 formGroup。然后运行一个方法来映射分区并调用另一个方法将它们创建为 formGroups。
** new-season-component.html**
<form [formGroup]="chooseDivisions">
<ng-template matStepLabel>Choose which teams are part of this season</ng-template>
<div formArrayName="divisions">
<div *ngFor="let division of chooseDivisions.get('divisions').controls; let i = index;">
<div [formGroupName]="i">
<mat-checkbox formControlName="division">{{ division[i].name }}</mat-checkbox>
</div>
</div>
</div>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</form>
我已经使用了各种在线材料来达到这一点 - 包括这篇文章,但似乎没有一个是我正在寻找的 - 即在加载时添加一个部门列表作为复选框,而不是单击按钮添加的功能一个新的空白表单控件。
我显然在做一些根本错误的事情。我什至应该在这里使用反应形式吗?
解决方案
表单数组必须始终是表单组的子级,否则会抛出错误。因此,您必须在 ngOnInit 中以表单数组作为控件来启动一个表单组。
this.divisionsFormGroup = this.fb.group({
divisions: this.fb.array([])
});
我建议之后推入表单数组:
this.allDivisions.map(divisionFromStore => this.divisionsFormGroup.controls.divisions.push(createDivisionFormControl(divisionFromStore));
然后你的HTML:
<form [formGroup]="divisionsFormGroup">
<ng-template matStepLabel>Choose which teams are part of this season</ng-template>
<div formArrayName="divisions">
<div *ngFor="let division of divisions.controls; let i = index;"> // I can't quite recall if you can call controls off of the formArrayName, or if you have to use divisionsFormGroup.controls.divisions.controls
<div [formControlName]="i">
<mat-checkbox>{{ division.controls.name.value }}</mat-checkbox> // Try just division.name if that doesn't work
</div>
</div>
</div>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</form>
打字的问题...
- 转换表单组创建方法的返回值
return this.fb.group({etc}) as AbstractControl // I can't quite recall if it'll error out and say there's no overlap between properties. If that doesn't work, do the below...
- 请改用表单数组
setValue()
。
const arrayOfAllDivisionsFormGroups = this.allDivisions.map(divisionFromStore => createDivisionFormControl(divisionFromStore));
this.divisionsFormGroup.controls.divisions.setValue(arrayOfAllDivisionsFormGroups);
不应该有类型冲突 b/csetValue()
需要any[]
。
推荐阅读
- node.js - 如何在 Azure DevOps 构建结果中添加新选项卡以显示 HTML 内容?
- java - 从提供的目录中的文件名创建字符串列表
- php - 当参数值丢失或等号丢失时,Laravel 5.2 验证失败
- html - 如何在元素中使用背景属性对该图标进行编码?
- excel - 是否有任何自动化方法可以将 Azure Blob 存储中的 CSV 文件转换为 Excel 表?
- angular - 使用 RxJs BehaviorSubject 在 Angular 拦截器中等待数据
- javascript - e.currentTarget 用于材质 ui 按钮
- python - 如何删除熊猫中所有行中具有重复值的列
- java - 在 Spring Controller 中丢弃 Http 请求
- matrix - 将函数应用于矩阵的每一列