Angular - 如何对 FormArray 中的项目重新排序?

问题描述 投票:0回答:3

我有一个包含一堆控件的大表单。在这个表单中,我有一系列表单组,它们是我的“规则”。

我需要添加更改规则顺序的功能,不仅是其值,而且是其在 DOM 中的视觉位置。

这是我的设置:

这些规则中的每一个都是一个具有自己的表单组等的组件。它们最初显示的顺序基于其当前存储的处理顺序值。

在每条规则下方,我都有一个按钮可以向上或向下移动规则,这就是我正在研究的内容。

对于反应式表单,表单组的索引是否决定其在组件 UI 中的位置?例如,如果我想向上移动一条规则,我可以将该表单组索引更改为

currentIndex-1
,或者将上面的规则更改为
+1
以便更改位置吗?

我的目标是能够在 UI 上上下移动这些组件。由于此页面上的规则数量较多,我试图远离拖放库。

更新:

这是我的设置的一个小窍门:

https://plnkr.co/edit/S77zywAa7l900F0Daedv?p=preview

angular
3个回答
32
投票

FormArray
上有多种方法,例如
removeAt
insert
可以帮助您实现目标。

模板.html

<button class="button" (click)="move(-1, i)">Move Up</button> &nbsp; 
<button class="button" (click)="move(1, i)">Move Down</button>

组件.ts

move(shift, currentIndex) {
  const rules = this.rulesForm.get('ruleData.rules') as FormArray;

  let newIndex: number = currentIndex + shift;
  if(newIndex === -1) {
    newIndex = rules.length - 1;
  } else if(newIndex == rules.length) {
    newIndex = 0;
  }

  const currentGroup = rules.at(currentIndex);
  rules.removeAt(currentIndex);
  rules.insert(newIndex, currentGroup)
}

Plunker 示例


8
投票

这是一个简短的 es6 版本的“move”方法:

move(shift: number, i: number,): void {
    const { controls } = this.rulesForm.get('ruleData.rules');
    [ controls[i], controls[i+shift] ] = [ controls[i+shift], controls[i] ];
    this.rulesForm.patchValue(controls);
}

Plunker 示例


0
投票

Angular CDK 提出了 util 函数

moveItemInArray
;

import { moveItemInArray } from '@angular/cdk/drag-drop';

move(fromIndex: number, toIndex: number):void {
  moveItemInArray(this.rulesForm.get('ruleData.rules'), fromIndex, toIndex);
}
© www.soinside.com 2019 - 2024. All rights reserved.