我有一个具有以下结构的动态反应形式,旨在创建一个矩阵,该矩阵由任意数量的用户组成,每个用户均具有任意数量的userRoles:
this.form = this.formBuilder.group({
users: this.formBuilder.array(
this.usersRoles.map(
urs => this.formBuilder.group({
userRoles: new FormArray(
urs.map(r => new FormControl(r))
)
})
)
)
});
在上面的代码中,this.usersRoles是一个布尔值数组(例如0:true,1:false,2:false等),表示存储为FormControl(r)的复选框的初始状态。>
在此结构中填充数据后,表单将在表中呈现如下:
<tr formArrayName="users" *ngFor="let user of form['controls']['users']['controls']; index as u">
<td *ngFor="let userRole of user['controls']['userRoles']['controls']; index as i">
<input type="checkbox" [formControlName]="i">
</td>
</tr>
我的问题是将呈现的表单绑定到控件的基础数组。如上所述,此html生成错误“ control.registerOnChange不是函数”,这似乎表明模板无法从表单组中找到控件。
我觉得我在这里遗漏了一些简单的东西,但无法完全弄清楚它可能是什么。例如,我尝试向包装复选框的td中添加formArrayName =“ userRoles”,认为这是将一个用户行中的复选框与另一用户行区分开来所必需的,但是随后收到“找不到路径的控件:'users- > userRoles'”。
有趣的是,在触发错误之前,第一个用户订单呈现良好(尽管没有选中任何框),所以我认为我正在处理forArrayName东西……任何帮助都非常感谢!
答案 0 :(得分:0)
实际上,事实证明这是一个需要向标记添加更多属性的问题,并且由于使用表而变得复杂,这限制了嵌套的机会,就像使用div一样。幸运的是,我们有ng-container可以帮助您。
此处的关键是确保html元素反映表单定义,因此我们需要为父数组使用一个重复元素(ng-container)-标记为formArrayName =“ users”,并标记另一个重复元素(td)使用formArrayName =“ userRoles”作为子数组。子数组需要一个包装器,并用我们的tr提供的formGroupName标记。这将从父数组ngFor的索引中获取动态名称。
下面的模板碎片可以完美工作。
<ng-container formArrayName="users" *ngFor="let user of form['controls']['users']['controls']; index as u">
<tr [formGroupName]="u">
<td formArrayName="userRoles" *ngFor="let userRole of user['controls']['userRoles']['controls']; index as i">
<input type="checkbox" [formControlName]="i">{{i}}
</td>
</tr>
</ng-container>