麻烦以Angular 6反应形式绑定复选框的嵌套数组

时间:2019-01-01 06:48:00

标签: angular6 angular-reactive-forms

我有一个具有以下结构的动态反应形式,旨在创建一个矩阵,该矩阵由任意数量的用户组成,每个用户均具有任意数量的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东西……任何帮助都非常感谢!

1 个答案:

答案 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>