【问题标题】:Dynamically adding to a form array that is in another form array in angular2动态添加到 angular2 中另一个表单数组中的表单数组
【发布时间】:2017-01-27 02:53:03
【问题描述】:

我有一个组件类的代码如下:

import {FormBuilder, FormGroup, Validators, FormControl, FormArray} from '@angular/forms'

...
form: FormGroup
constructor(private _fb: FormBuilder) { }

this.form = this._fb.group({
      name: ['', [Validators.required]],
      sortItem: this._fb.array([
        this.initSort(),
      ])
    });

initSort(){
    return this._fb.group({
      locationName: ['', [Validators.required]],
      locationItems: this._fb.array([
        this.initSortItems()
      ])
    })
  }

initSortItems(){
    return this._fb.group({
      itemName: ['', [Validators.required]],
      itemPicture: ['', []],
    })
  }

addSort(){
    const control = <FormArray>this.form.controls['sortItem'];
    control.push(this.initSort());
  }

addSortLocationItem(i?: number, t?: number){
    // add more locationItems to the sort. This is where I am stuck

// if tried the following with no avail  (<FormArray>this.form.get('sortItem').value[i].controls).push(this.initSortItems());

  }

我正在尝试添加更多 locationItems,但我在 addSortLocationItem() 方法中尝试的方法不起作用。如何访问 sortItem 正确迭代的表单控件并将多个位置项添加到该迭代?

这是我的标记:

<div class="">
  <a (click)="addSort()" style="cursor: default">
    Add Sort Locations +
  </a>
</div>

<div formArrayName="sortItem">
  <div *ngFor="let sortLocation of form.controls.sortItem.controls; let i=index">
      <!-- address header, show remove button when more than one address available -->
      <div>
          <span>Location {{i + 1}}</span>
          <span *ngIf="form.controls.sortItem.controls.length > 1"
              (click)="removeAddress(i)">
          </span>
      </div>

      <div [formGroupName]="i">
          <!--name-->
          <div>
              <label>Location Name</label>
              <input type="text" formControlName="locationName">
              <!--display error message if street is not valid-->
              <small [hidden]="form.controls.sortItem.controls[i].controls.locationName.valid">
                  Street is required
              </small>
          </div>

          <div formArrayName="locationItems">
            <div *ngFor="let eachItem of form.controls.sortItem.controls[i].controls.locationItems.controls; let t=index">
                <!-- address header, show remove button when more than one address available -->
                <div class="">
                  <a (click)="addSortLocationItem(i,t)" style="cursor: default">
                    Add Items +
                  </a>
                </div>

                <div>
                    <span>Location Item {{t + 1}}</span>
                    <span *ngIf="form.controls.sortItem.controls[i].controls.locationItems.controls[t].length > 1"
                        (click)="removeAddress(t)">
                    </span>
                </div>

                <div [formGroupName]="t">
                    <!--name---->
                    <div>
                        <label>Item Name</label>
                        <input type="text" formControlName="itemName">
                        <!--display error message if street is not valid-->
                        <small [hidden]="form.controls.sortItem.controls[i].controls.locationItems.controls[t].controls.itemName.valid">
                            Name is required
                        </small>
                    </div>
                  </div>
              </div>
          </div>
      </div>
  </div>
</div>

对此的任何帮助将不胜感激。

【问题讨论】:

    标签: arrays forms angular


    【解决方案1】:

    如果imain controlindex,那么你可以通过以下方式轻松获得:

    addSortLocationItem(i: number, t: number) {
      const control = this.sortItem.get(`${i}.locationItems`) as FormArray;
      control.push(this.initSortItems());
    }
    

    而且,作为建议,我建议您创建一些变量,以提高code 的可读性。

    form: FormGroup;
    name: FormControl;
    sortItem: FormArray;
    

    这个:

    <div *ngFor="let sortLocation of form.controls.sortItem.controls; let i=index">
    ...
    <div *ngFor="let eachItem of form.controls.sortItem.controls[i].controls.locationItems.controls; let t=index">
    

    可以替换为:

    <div *ngFor="let sortLocation of sortItem.controls; let i = index">
    ...
    <div *ngFor="let eachItem of sortLocation.get('locationItems').controls; let t = index">
    

    完整代码:

    import { Component, OnInit } from '@angular/core';
    import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'
    
    @Component({
      ...
    })
    export class BlaBlaComponent implements OnInit {
    
      form: FormGroup;
      name: FormControl;
      sortItem: FormArray;
    
      constructor(private readonly formBuilder: FormBuilder) { }
    
      ngOnInit(): void {  
        this.name = this.formBuilder.control('', [Validators.required]);
        this.sortItem = this.formBuilder.array([this.initSort()]);
    
        this.form = this.formBuilder.group({
          name: this.name,
          sortItem: this.sortItem
        });
      }
    
      initSort() {
        return this.formBuilder.group({
          locationName: ['', [Validators.required]],
          locationItems: this.formBuilder.array([
            this.initSortItems()
          ])
        })
      }
    
      initSortItems() {
        return this.formBuilder.group({
          itemName: ['', [Validators.required]],
          itemPicture: ['', []],
        })
      }
    
      addSort() {
        this.sortItem.push(this.initSort());
      }
    
      addSortLocationItem(i: number, t: number) {
        const control = this.sortItem.get(`${i}.locationItems`) as FormArray;
        control.push(this.initSortItems());
      }
     }
    

    PS:我没有测试,如果我忘记了什么,请告诉我。

    【讨论】:

    • 您先生是个天才!谢谢它让我发疯。按计划工作,感谢 html 部分的速记。
    • 我对表单数组有类似的问题,但这次是关于文件输入。请你看看这里,看看你能不能帮忙? stackoverflow.com/questions/41907471/…
    猜你喜欢
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2019-11-18
    相关资源
    最近更新 更多