具有动态选项的动态表单数组

时间:2019-07-16 03:08:51

标签: angular typescript angular-reactive-forms formarray

我想让学生能够在动态数量的学校科目中选择几个工作坊

1.-我有一个配置数组,该数组具有学生将为每个学科选择的选项数量

let configarray = {initdate: 2019-07-01, subjectnumber: 4};

在此示例中,学生可以为每个学科选择4个选项。

let b = this.FormGuardar.get("opciontaller") as FormArray; 
for (let i = 0; i < configarray.subjectnumber; i++) {
     let preregistro = this._fb.group({
         preregistroid: [],
         alumnoporcicloid:[],
         tallercurricularid: []
         });
         b.push(preregistro);
         this.arrayopcion.push({ taller: this.tallerselect }); //tallerselect will display
the options of every subject every subject will have a diferent options

此外,当我选择一个选项时,这是我的代码,用于删除配置中其他选择项中的所选选项。

    selectedTaller(id, index) {
    let seleccionados = [];
    let array = this.FormGuardar.get("opciontaller").value;
    for (let a of array) {
        if (a.tallercurricularid) {
            seleccionados.push(a.tallercurricularid);
        }
    }

    let disponibles = this.SelectTaller.filter(function (item) {
        return seleccionados.indexOf(item.tallercurricularid) == -1;
    });

    for (let i = 0; i < this.arrayopcion.length; i++) {
        let data = [...disponibles],
            control = ((this.FormGuardar.controls.opciontaller as FormArray).controls[i] as FormGroup).controls.tallercurricularid as FormControl,
            seleccionado = this.SelectTaller.find(x => x.tallercurricularid == control.value);
        (((this.FormGuardar.controls.opciontaller as FormArray).controls[i] as FormGroup).controls.clasificadorparaescolarid as FormControl).setValue(seleccionado ? seleccionado.clasificadorparaescolaresid.clasificadorparaescolaresid : null);
        seleccionado ? data.push(seleccionado) : null;
        this.arrayopcion[i].taller = data;
        seleccionado ? control.setValue(seleccionado.tallercurricularid) : null;
    }
}

这里的问题是我如何才能使此代码适用于动态数量的主题,并为每个研讨会提供动态选项?

1 个答案:

答案 0 :(得分:0)

要删除选项,请参见stackoverflow question

如果您选择即时创建列表,则可以进行类似see stackblitz

的操作

您有一个递归函数,该函数将索引,控件数组和带有选择选项的数组作为参数-在这种情况下,我在语言列表之间进行选择-

getLang(i, array, languageList) {
    return i == 0 ? languageList :
      this.getLang(i - 1, array, languageList.filter(x => x.name != array[i - 1].value))
  }

如果您有类似的功能

createStudent() {
  const auxiliar = new Array(this.configarray.subjectNumber).fill('')
    return new FormGroup(
      {
        name: new FormControl(),
        options: new FormArray(auxiliar.map(x => new FormControl()))
      }
    )
  }

您可以在ngOnInit中添加类似的内容

 this.formArray=new FormArray([]);
 this.formArray.push(this.createStudent())
 this.formArray.push(this.createStudent())

我们的表单就像

<form *ngIf="formArray" [formGroup]="formArray">
    <div *ngFor="let form of formArray.controls">
        <div [formGroup]="form">
            <input formControlName="name">
            <div formArrayName="options">
              <div *ngFor="let a of form.get('options').controls;let i=index" >
                 <select  [formControlName]="i">
                    <option value="null" disabled>Select Language</option>
                    <option *ngFor="let lang of 
                       getLang(i,form.get('options').controls,languageList)"
                       [value]="lang.name" >{{lang.name}}</option>
                </select>
           </div>
        </div>
    </div>
    <hr/>
  </div>
</form>

已更新,我们需要检查是否无法选择相同的语言,因此我们同意更改数组选项。所以,如果我们选择德语,多拉奇语,西班牙语和法语,并用西班牙语替换德语后,第三个选项变为空

this.formArray.controls.forEach(form => {
      form.get('options').valueChanges.subscribe(res => {
        res.forEach((x, index) => {
          if (index > 0 && res.slice(0, index).find(a=>a==x))
            (form.get('options') as FormArray).at(index).setValue(null, { emit: false })
        })
      })
    })