使用 Angular 6+ 表单数组复制动态 Select 框

Duplicate Dynamic Select Box using Angular 6+ Form Array

Select 框 1 是“路径”。 Select 框 2 是“SkillSet”。

我正在尝试根据按钮单击复制一组 select 框(路径和技能集)。因此,当我单击“添加”按钮时,select 框(路径和技能集)表单元素将被复制。这里的问题是 select 框 "Skillset" 元素的选项是动态的,因为它取决于 select 框 "Path".

问题如下: Step1:选择Path作为BackEnd,Skill会根据Path进行填充。在第二个 select 框中 select 编辑为 Java8。

Step2:点击添加按钮,所以select框路径和技能被复制。现在选择 select 框路径作为 FrontEnd。

Step3:第二行选择Path为FrontEnd后,第一行的selected Skill重置为空。 (在图片中我添加了两个路径)

问题的 StackBlitz 演示: https://stackblitz.com/edit/angular-duplicate-dynamic-select-box?file=null

期望是:我必须 select 每个路径和相应的技能。就像如果我选择 3 条不同的路径,那么我必须在 3 行不同的 select 框中选择 3 种不同的技能。

我尝试了很多解决方案。什么都没有解决。在这种情况下有人可以提供帮助吗?

对不起我的英语和错误的格式。感谢您的帮助!!!

您可以将 selected 路径的技能组推送到一个数组中,然后使用索引在 HTML 文件中访问它们。

在 .ts 文件中

import { Component } from '@angular/core';
import { FormGroup, FormArray, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  skillSetObj;
  majorPathObj;

  skillForm: FormGroup;
  skillList: FormArray;

  choosenPath;
  skillsForSelectedPath:any = [];  // <--- Declare a new array for the skillsets to be pushed

  constructor(private fb:FormBuilder) {

  }

  ngOnInit() {
    this.skillSetObj = {
      "BackEnd": ["Java8", "Node JS", "Python", "Dotnet"],
      "FrontEnd": ["Javascript ", "Angular ", "React", "Vue"],
      "Database": ["Oracle", "Postgres", "Mysql"]
    };

    this.majorPathObj = ["BackEnd", "FrontEnd", "Database"];

    this.skillForm = this.fb.group({
      skillFormArray: this.fb.array([this.createSkills()])
    });

    this.skillList = this.skillForm.get('skillFormArray') as FormArray;
  }

  createSkills(): FormGroup {
    return this.fb.group({
      majorPath: ['', Validators.compose([Validators.required])],
      skillSet: ['', Validators.compose([Validators.required])]
    });
  }

  getSkillFormGroup(index): FormGroup {
    const formGroup = this.skillList.controls[index] as FormGroup;
    return formGroup;
  }

  get skillFormGroup() {
    return this.skillForm.get('skillFormArray') as FormArray;
  }

  addNewSkill() {
    this.skillList.push(this.createSkills());
  }

  removeSkill(skillRowIndex) {
    this.skillList.removeAt(skillRowIndex);
  }

  prepareSkillSet(event, i) {
    this.skillsForSelectedPath[i]=this.skillSetObj[event.value];  // <--- Push the skills for the selected majorPath into the new array
    const formGroup = this.getSkillFormGroup(i);
    const choosenPath = formGroup.controls['majorPath'].value;
    this.choosenPath = choosenPath;
  }

}

** 在 HTML 文件中 **

<form [formGroup]="skillForm">

  <div formArrayName="skillFormArray">
      <div *ngFor="let skillArray of skillFormGroup.controls; let i=index">
          <div [formGroupName]="i">
              <div >
                  <mat-form-field appearance="outline">
                      <mat-select formControlName="majorPath"
                          (selectionChange)="prepareSkillSet($event, i)">
                          <mat-option *ngFor="let major of majorPathObj" value={{major}}>
                              {{major}}
                          </mat-option>
                      </mat-select>
                  </mat-form-field>
                  <mat-form-field appearance="outline">
                    <mat-select formControlName="skillSet">
                        <mat-option *ngFor="let skill of skillsForSelectedPath[i]" [value]="skill">   <!-- display the skills for the selected majorPath using the index of the newly created variable -->
                            {{skill}}
                        </mat-option>
                    </mat-select>
                </mat-form-field>
                  <button *ngIf="i===0" mat-fab color="accent" class="add-file-button mt-5"
                      (click)="addNewSkill()" aria-label="Add Skill">
                      <mat-icon>add</mat-icon>
                  </button>
                  <button *ngIf="i!==0" mat-fab color="warn" class="add-file-button"
                      (click)="removeSkill(i)" aria-label="Remove Skill">
                      <mat-icon>remove</mat-icon>
                  </button>
              </div>

          </div>

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

所以每次 majorPath 技能对象也会更新,你可以 select 新 selected 的相应技能 主要路径

输出如下所示