簡體   English   中英

Angular 5 Reactive Forms-通過FormArray的復選框ID

[英]Angular 5 Reactive Forms - pass checkbox Id's for FormArray

我正在使用反應形式FormGroup,FormBuilder和FormArray。 我有一個FormArray,我想在其中循環遍歷一個外部數組,創建一個復選框列表,然后將這些復選框的ID傳遞給我的FormArray。

我的組件打字稿看起來像:

export class AppComponent  {
  form: FormGroup;

  sites = [ "site-1", "site-2", "site-3", "site-4" ];

  constructor(private fb: FormBuilder){ 
  }

  ngOnInit() {
    this.form = this.fb.group({
      type: [ '', Validators.required ],
      sites: this.fb.array([
        this.fb.group({
          siteId: [ '', Validators.required ]
        })
      ])
    })
  }
}

還有我的html ...

<form [formGroup]="form">

  <input type="checkbox" formControlName="type" id="type">
  <label for="type">Type</label>

  <div class="checkbox-group" style="margin-top:40px">
      <div class="checkbox-wrap" id="productsContainer">
          <input type="checkbox" id="all">
          <label for="all">All mills</label>
          <div *ngFor="let site of sites; let i = index">
              <input type="checkbox" [id]="i" /> 
              <label [for]="i"> {{ site }} </label>
          </div>
      </div>
  </div>
</form>

我知道我需要將formArrayName傳遞到html中,但是在嘗試傳遞formArrayName =“ sites”,然后將循環中的“ i”用作formGroupName時遇到控制台錯誤。 我究竟做錯了什么?

這是具有完整設置的StackBlitz ...

https://stackblitz.com/edit/angular-rcfnwi?file=app%2Fapp.component.html

您需要使用與站點列表中的項目相對應的單個FormControl填充FormArray。 在我的fork示例中,我在FormGroup( https://stackblitz.com/edit/angular-hilz9h )的初始化中通過映射sites數組並生成默認值為false(未選中)的FormControls進行了此操作。 我還刪除了圍繞站點FormArray的嵌入式FormGroup,以使其更加簡單。 然后,我使用與ts文件中FormArray的“站點”名稱相對應的字符串屬性,將formArrayName指令添加到包裝div中。 最后,我添加了一個[formControlName]指令,並將每個輸入的ngFor索引傳遞給它,以對應於FormArray控件的數組索引。 FormArray在內部通過索引跟蹤其控件。

因此,您的ngOnInit現在看起來像:

ngOnInit() {
    this.form = this.fb.group({
      type: [ '', Validators.required ],
      sites: this.fb.array(this.sites.map(s => this.fb.control(false)),
          [ Validators.required ])
    })
  }

現在您的html文件如下所示:

<form [formGroup]="form">

  <input type="checkbox" formControlName="type" id="type">
  <label for="type">Type</label>

  <div class="checkbox-group" style="margin-top:40px">
      <div class="checkbox-wrap" id="productsContainer" formArrayName="sites">
          <input type="checkbox" id="all">
          <label for="all">All mills</label>
          <div *ngFor="let site of sites; let i = index">
              <input type="checkbox" [id]="i" [formControlName]="i"/> 
              <label [for]="i"> {{ site }} </label>
          </div>
      </div>
  </div>
</form>

<pre> {{ form.value | json }}</pre>

確實可以解決問題,但我認為顯然不是Form Array。 當我們進行一系列檢查時,我們必須了解有兩個獨立的概念:表單和數據。 是的,這兩個概念不是必須相等的。

我選擇創建像

//we create a FormGroup array transform the array "this.sites"
const controls:FormGroup[]=this.sites.map(x=>{
  return this.fb.group({
    site:false
  })
});
//in this.form I use this array of FormGroup
this.form = this.fb.group({
  type: ['', Validators.required],
  sites: this.fb.array(controls)
})

好,當我們制作表格時,form.value可以像

{
  "type": "", 
  "sites": [ 
    { "site": false }, { "site": true }, { "site": false }, { "site": true }
  ]
} 

然后,在提交中,我們必須將form.value轉換為我們喜歡的數據

  submit(form: FormGroup) {
    if (form.valid) {
      //create an array of sites
      let sites: string[] = [];
      let i: number = 0;
      form.value.sites.forEach((x:any) => {
        if (x.site)
          sites.push(this.sites[i]);
        i++;
      });
      //Our data will be
      let data = {
        type: form.value.type,
        sites: sites
      }
      console.log(data);
    }
  }

最后,形式:

<form [formGroup]="form" (submit)="submit(form)" novalidate">
<input formControlName="type">
  <div formArrayName="sites" *ngFor="let site of form?.get('sites').controls;let i=index">
    <div [formGroupName]="i">
      <--!see that formControlName is "site"
      and the labels of the check use the array this.sites -->
      <input type="checkbox" formControlName="site" /> {{sites[i]}}
    </div>
  </div>
  <button>send</button>
</form>

所有人都在問為什么在地球上,到底是什么東西? 所有的事情一定太復雜了嗎? 我的回答是,它並不那么復雜。 此外,想象一下如何用數據填充表格。

//if data={type:"a",sites:["site-2","site-4"], we create the form like
const controls:FormGroup[]=this.sites.map(x=>{
  return this.fb.group({
    site:data.sites.indexOf(x)>=0; //true or false
  })
});
this.form = this.fb.group({
  type: [data.type, Validators.required],
  sites: this.fb.array(controls)
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM