在响应式表单中嵌套 Headers 和 Table

Nested Headers and Table in Reactive Forms

我有几个类别,每个类别有几个materials/products。我有一个问题,因为当我决定删除一个类别中的 material/product 时,我也删除了另一个类别中的 material/product?如何使用反应形式来解决这个问题?我如何独立删除一个 material 而不是另一个?这是我的代码 CODE LINK

的 link
patchValues() {
    let rows = this.myForm.get('rows') as FormArray;
    this.orders.forEach(material => {
      material.materials.forEach(x => {
      rows.push(this.fb.group({material_id: x.id,material_name: x.name, quantity: x.qty}))
    })
      })

  }

  onDeleteRow(rowIndex) {
    let rows = this.myForm.get('rows') as FormArray;
    rows.removeAt(rowIndex)
  }

您需要创建一个数组数组。一不留神很容易迷路,不过有点像:

constructor(private fb: FormBuilder) { 
    this.myForm=this.createForm(this.orders);  //I like pass the argument
  }

  createForm(orders:any) //Our form has only an arrayForm "data"
  {
    return this.fb.group(
      {
        data:this.fb.array(this.createOrders(orders))
      }
    )
  }
  createOrders(orders:any)
  {
    //using map, with each "order" we create a formGroup, so we return a formGroup[]
    return orders.map(x=>
    {
      return this.fb.group({  
        id: x.id,
        name: x.name,
        address: x.adress,
        materials:this.fb.array(this.createMaterial(x.materials)) //<--call a function

      })
    })
  }
  createMaterial(materials:any)  //like the above function return a fromGroup[]
  {
    return materials.map(x=>{
      return this.fb.group({material_id: x.id,material_name: x.name, quantity: x.qty})
    })
  }

模板是这样的

    <form class="form-horizontal" [formGroup]="myForm" (ngSubmit)="onCreateProduct()" >
      <div class="card" formArrayName="data">
        <div class="card-block" 
          *ngFor="let category of myForm.get('data').controls;let i=index">
 <!--see that to show the name of categorie we are using the array categories
     this are not included in the myForm, it's the "variable" categories-->
        CATEGORY:   {{ categories[i].name }}  
        <br>
          <table class="table" [formGroupName]="i" >
            <thead>
              <tr>
                <th>Material ID</th>
                <th>Material Name</th>
                <th>Qty</th>
                <th>Action</th>
              </tr>
            </thead>
            <tbody formArrayName="materials">
              <tr *ngFor="let row of category.get('materials').controls; let j = index" [formGroupName]="j">
                <td>{{row.value.material_id}}</td>
                <td>{{row.value.material_name}}</td>
                <td>{{row.value.quantity}}</td>
                <td><button type="button" (click)="onDeleteRow(i,j)"> <i class="icofont icofont-ui-delete"></i> Remove</button></td>
              </tr>
            </tbody>

          </table>
        </div>
      </div>
    </form>

嗯,思路是一样的,

createForm(categories:any,orders:any) //Our form has only an arrayForm "data"
  {
    return this.fb.group(
      {
        //we send orders[0].materials, orders is an array (sorry)
        data:this.fb.array(this.createOrders(categories,orders[0].materials))
      }
    )
  }
  createOrders(categories:any,materials:any) //<--received materials
  {
    //using map, with each "categories" we create a formGroup, so we return a formGroup[]
    return categories.map(x=>
    {
      return this.fb.group({  
        name: x.name,
        materials:this.fb.array(this.createMaterial(materials)) //<--call a function

      })
    })
  }