如何在 Angular 中以 FormArray 反应形式获得唯一值?

How to get unique value in FormArray reactive form in Angular?

我创建了一个 stackblitz 应用程序来演示我的问题:https://angular-ry1vc1.stackblitz.io/

我在 select HTML 列表中有 formArray 值。每当用户更改 selection 时,它应该在页面上显示 selected 值。问题是我如何才能只显示当前的 selection 并且它应该 NOT 覆盖之前 selected 的值。我想知道如何使用 key 使值的占位符唯一。 TIA

form.html

<form [formGroup]="heroForm" novalidate class="form">
  <section formArrayName="league" class="col-md-12">
    <h3>Heroes</h3>
    <div class="form-inline" *ngFor="let h of heroForm.controls.league.controls; let i = index" [formGroupName]="i">
      <label>Name</label>
      <select (change)="onSelectingHero($event.target.value)">
        <option *ngFor="let hero of heroes" [value]="hero.id" class="form-control">{{hero.name}}</option>
      </select> <hr />
      <div>
        Hero detail: {{selectedHero.name}}
      </div> <hr />
    </div>
    <button (click)="addMoreHeroes()" class="btn btn-sm btn-primary">Add more heroes</button>
  </section>
</form>

component.ts

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {
  heroes = [];
  heroForm: FormGroup;
  selectedHero;

  constructor(
    private fb: FormBuilder,
  ) {
    this.heroForm = fb.group({
      league: fb.array([
        this.loadHeroes(),
        this.loadHeroes(),
        this.loadHeroes()
      ])
    });
  }

  ngOnInit() {
    this.listHeroes();
  }

  public addMoreHeroes() {
    const control = this.heroForm.get('league') as FormArray;
    control.push(this.loadHeroes());
  }

  public loadHeroes() {
    return this.fb.group(
      {
        id: this.heroes[0],
        name: '',
        level: '',
        skill: '',
      }
    );
  }  

  public listHeroes() {
    this.heroes = [
      {
        id: 1,
        name: 'Superman'
      },
      {
        id: 2,
        name: 'Batman'
      },
      {
        id: 3,
        name: 'Aquaman'
      },
      {
        id: 4,
        name: 'Wonderwoman'
      }      
    ];
  }

  public onSelectingHero(heroId) {
    this.heroes.forEach((hero) => {
      if(hero.id === +heroId) {
        this.selectedHero = hero;
      }
    });
  }
}

如果这样做的目的是通过数组元素仅显示选定的英雄而不是替换所有选定的值,那么您可以使用数组形式的元素获得一些帮助。

A. onSeletingHeroselectedHero 不是必需的,我通过 formControlName 属性使用表单值替换了它,在此例如 id 控件是 selecth.value.id是获取选中值id的方法。

    <select formControlName="id">
        <option *ngFor="let hero of heroes;" [value]="hero.id" class="form-control">{{hero.name}}</option>
      </select> <hr />
      <div>
        Hero detail: {{getHeroById(h.value.id).name}}
      </div> <hr />
    </div>

B. 为了得到选中的英雄我加了一个getHeroById方法。

  getHeroById(id: number) {
    return id ? this.heroes.find(x => x.id === +id) : {id: 0, name: ''};
  }

希望这些信息能解决您的问题。干杯