首页 文章

在 Angular 中以动态反应形式添加项目

提问于
浏览
3

我正在尝试在 Angular 5 中构建一个嵌套的被动表单。我能够在一个级别推送项目,但无法在第二级推送项目。

ngOnInit() {
 this.orderForm = this.formBuilder.group({
  customerName: '',
  email: '',
  items: this.formBuilder.array([this.createItem()])
});
}

 createItem(): FormGroup {
    return this.formBuilder.group({
      name: 'a',
      description: 'b',
      price: 'c',
      //subItems: this.formBuilder.array([this.createSubItem()])
    });
 }

 //createSubItem(): FormGroup {
    //return this.formBuilder.group({
      //subname: 'abc'
    //});
 //}

 addItem(): void {
    this.items = this.orderForm.get('items') as FormArray;
    //this.subItems = this.items.get('subItems') as FormArray;
    //this.subItems.push(this.createSubItem());
    this.items.push(this.createItem());
 }

在上面的代码中,未注释的代码可以正常工作。我在项目中有更多的子项目,注释代码是我想要实现的,但它不起作用。

任何机构都可以告诉我如何实现这一目标吗?

对于未注释的代码,我在这样的 html 中显示数据并且它运行良好。如果任何正文在代码级别有解决方案,请告诉我如何更新嵌套项目的 html。

<form [formGroup]="orderForm">
<div formArrayName="items" *ngFor="let item of orderForm.get('items').controls; let i = index;">
    <div [formGroupName]="i">
      <input formControlName="name" placeholder="Item name">
      <input formControlName="description" placeholder="Item description">
      <input formControlName="price" placeholder="Item price">
    </div>
  </div>
  <input type="button" value="sldkj" (click)="addItem()">
</form>

解:

首先,我设法像这样 pre-populate 值。

obj = [
    {
      'name': "umair",
      'description': "desc1",
      'subItems': [
        {
          'subname': 'value'
        },
        {
          'subname': 'value2'
        },
        {
          'subname': 'value3'
        }
      ]
    },
    {
      'name': "ali",
      'description': "desc2",
      'subItems': [
        {
          'subname': 'valu4'
        },
        {
          'subname': 'value5'
        },
        {
          'subname': 'value6'
        }
      ]
    }
  ]

  ngOnInit() {
    this.createForm(this.obj);
    console.log(this.orderForm);
  }

  createForm(obj) {
    var arr = [];
    for (var i = 0; i < obj.length; i++) {
      arr.push(this.createItem(obj[i]));
    }
    this.orderForm = this.formBuilder.group({
      items: this.formBuilder.array(arr)
    });
  }

  createItem(obj): FormGroup {
    var subArr = [];
    for (var i = 0; i < obj.subItems.length; i++) {
      subArr.push(this.createSubItem(obj.subItems[i]));
    }
    return this.formBuilder.group({
      name: obj.name,
      description: obj.description,
      subItems: this.formBuilder.array(subArr)
    });
  }

  createSubItem(subItem): FormGroup {
    return this.formBuilder.group({
      subname: subItem.subname
    });
  }

在下面的'标记'答案的帮助下,我设法添加子项并填写 html 如下。

<form [formGroup]="orderForm">
  <!-- <label>{{item.get('name').value}}</label> -->
  <div formArrayName="items" *ngFor="let item of orderForm.controls.items.controls; let i = index;">
    <div formGroupName="{{i}}">
      <!-- <label>{{item.get('name').value}}</label> -->
      <input formControlName="name" placeholder="Item name">
      <input formControlName="description" placeholder="Item description">

      <input type="button" value="subAdd" (click)="addSubItems(i)">

      <div formArrayName="subItems" *ngFor="let subItem of item.controls.subItems.controls; let idx = index;">
        <div formGroupName="{{idx}}">
          <!-- <label>{{subItem.get('subname').value}}</label> -->
          <input formControlName="subname" placeholder="Item name">
        </div>
      </div>

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

addSubItems(_index: any): void {
    var a = this.orderForm['controls']['items']['controls'][_index] as FormGroup;
    this.subItems = a.get('subItems') as FormArray;
    var newSubItem = {
      'subname': 'value6'
    }
    this.subItems.push(this.createSubItem(newSubItem));
  }

2 回答

  • 3

    首先,让我们先了解你的工作。

    你在 formarray 中制作了一个 formarray。所以这意味着它有两个循环。所以你必须* ng 为第一个和* ng 为第二个。最后,这意味着您的项目有索引****i ,子项目有j。然后你可以添加addSubItems(i)来推送你的子项目。

    你的 HTML 应该是这样的:

    <form [formGroup]="orderForm">
      <div formArrayName="items">
         <div *ngFor="let arrays of orderForm.controls.items.controls; let i = index;">
            <div formGroupName="{{i}}">
              <input formControlName="name" placeholder="Item name">
              <input formControlName="description" placeholder="Item description">
              <input formControlName="price" placeholder="Item price">
              <input type="button" value="subAdd" (click)="addSubItems(i)"> <-- here your button -->
              <div formArrayName="subItems">
                 <div *ngFor="let item of arrays.controls.subItems.controls; let j = index;">
                    <div formGroupName="{{j}}">
                       <input formControlName="subname" placeholder="Item subname">
    

    您的 addSubItems 应该类似于:

    addSubItems(_index: any): void {
        this.item = this.orderForm['controls']['items']['controls'][_index] as FormGroup;
        this.subItems = this.item.get('subItems') as FormArray;
        this.subItems.push(this.createSubItem());
    
  • 1

    为了减少代码量,这些可以很少重构addSubItems(index) to addSubItems(item)

    <form [formGroup]="orderForm">
      ...
      <div formArrayName="items" *ngFor="let item of orderForm.controls.items.controls; let i = index;">
          ...
          <input type="button" value="subAdd" (click)="addSubItems(item)">
      </div>
      ...
    </form>
    
    addSubItems(item: FormGroup): void {    
        this.subItems = item.get('subItems') as FormArray;
        var newSubItem = {
          'subname': 'value6'
        }
        this.subItems.push(this.createSubItem(newSubItem));
      }
    

    所以,不需要按索引查找项目:var a = this.orderForm['controls']['items']['controls'][_index] as FormGroup;,因为你已经可以通过item: FormGroup

    StackBlitz 演示

相关问题