typescript 有没有更好的方法可以在React式表单中突出显示选定的表单数组项?

wmvff8tz  于 2022-11-26  发布在  TypeScript
关注(0)|答案(4)|浏览(131)

我有一个球员名单,我通过引入一个布尔标志来显示各个玩家的详细信息(isPlayerSelected)。此方法的一个缺点是页面响应速度慢(当有更多数量的项目时),因为它必须使用patchValue更新每个formGroup中的布尔标志。有没有更好的方法来代替引入布尔标志?
请帮助。我已经附上了StackBlitz链接以及

selectPlayer(player: any) {
    player.isPlayerSelected = !player.isPlayerSelected;
    const selectedPlayer = this.playerDetailsControls.find(
      (item) => player?.id === item.get('id')?.value
    );
    const otherPlayers = this.playerDetailsControls.filter(
      (item) => player.id !== item.get('id')?.value
    );
    selectedPlayer?.patchValue({
      isPlayerSelected: true,
    });
    otherPlayers.map((item) => {
      item?.patchValue({
        isPlayerSelected: false,
      });
    });
  }

HTML语言

<form [formGroup]="form">
    <div formArrayName="playerDetails">
      <div *ngFor="let control of playerDetailsControls; let i = index">
        <div [formGroupName]="i">
          <div *ngIf="control.get('isPlayerSelected')?.value">
            Player Name : <input formControlName="playerName" /><br /><br />
            Role: <input formControlName="role" /><br /><br />
            Country: <input formControlName="country" /><br /><br />
            <hr />
          </div>
        </div>
      </div>
    </div>
  </form>

Stackblitz

de90aj5v

de90aj5v1#

如果你得到了选中的播放器窗体控件,那么你可以直接在窗体中使用它
第一个

twh00eeo

twh00eeo2#

为什么不重用现有的变量selectedIndex呢?你可以像(click)="selectedIndex = i"一样设置它。
然后你就可以摆脱你的整个selectPlayer函数。
在播放器详细信息部分,您甚至不必遍历整个数组,只需根据selectedIndex变量直接绑定到formGroup即可。

zy1mlcev

zy1mlcev3#

正如Fabian Strathaus所写的,你只需要坚持索引,用像isPlayerSelected这样的字段污染对象不是一个好主意,因为这将在保存时发送到服务器。
我已经修改了stackblitz,作为您可以使用的示例。

eh57zj3b

eh57zj3b4#

要解决它最好是使用React形式的性质。
在这个例子中,我创建了一个“FormDetailSelected”,这个formGroup帮助我创建了一个动态的表单细节。

<div>
  <div *ngFor="let playerDetail of playerDetailsFromServer; let i = index">
    <label (click)="changeFormDetail(i)">
      {{ playerDetail.playerName }}
    </label>
  </div>

  <hr />

  <h3>Player Details</h3>
  <div>
    <form [formGroup]="formDetailSelected">
      <div>
        Player Name : <input formControlName="playerName" /><br /><br />
        Role: <input formControlName="role" /><br /><br />
        Country: <input formControlName="country" /><br /><br />
        <hr />
      </div>
      <button (click)="save()" [disabled]="!form.valid">Save</button>
    </form>
  </div>
</div>

技术支持

export class PlayersListComponent implements OnInit {
  form: FormGroup;
  formDetailSelected: FormGroup;
  playerDetailsFromServer = [];
  selectedIndex: number = 0;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.playerDetailsFromServer = [
      {
        id: 'id1',
        playerName: 'Sachin',
        country: 'INDIA',
        role: 'Batsman',
      },
      {
        id: 'id2',
        playerName: 'Ponting',
        country: 'Australia',
        role: 'Batsman',
      },
      {
        id: 'id3',
        playerName: 'Kallis',
        country: 'RSA',
        role: 'All Rounder',
      },
      {
        id: 'id4',
        playerName: 'Lara',
        country: 'WEST INDIES',
        role: 'Batsman',
      },
      {
        id: 'id5',
        playerName: 'Flintoff',
        country: 'ENGLAND',
        role: 'All Rounder',
      },
    ];

    this.form = this.fb.group({
      playerDetails: this.fb.array([]),
    });

    const playerDetailsControl = this.form.get('playerDetails') as FormArray;

    for (let { id, isPlayerSelected, country, playerName, role } of this
      .playerDetailsFromServer) {
      const formGroup = new FormGroup({
        id: new FormControl(id),
        isPlayerSelected: new FormControl(isPlayerSelected),
        country: new FormControl(country),
        playerName: new FormControl(playerName),
        role: new FormControl(role),
      });
      playerDetailsControl.push(formGroup);
    }

    this.changeFormDetail(0);
  }

  save() {
    console.log('Saved Details', this.form.value);
  }

  changeFormDetail(i: number) {
    this.selectedIndex = i;
    let array = this.form.get('playerDetails') as FormArray;
    this.formDetailSelected = array.controls[this.selectedIndex] as FormGroup;
  }
}

有了这个逻辑,您就不需要不断地重复“is selected”条件。

相关问题