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

21

我有一个包含许多控件的大表单。在这个表单中,我有一组表单组成为“规则”。

我需要添加更改规则顺序的功能,不仅可以更改其值,还可以更改其在DOM中的可视位置。

这是我的设置样子:

enter image description here

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

在每个规则下面,我有一个向上或向下移动规则的按钮,这就是我正在开发的内容。

使用响应式表单,表单组的索引是否确定其在组件UI中的位置?例如,如果我想向上移动一个规则,我是否可以将该表单组的索引更改为currentIndex-1,并将位于上方的规则更改为+1以交换位置?

我的目标是能够在UI上上下移动这些组件。由于此页面上的规则数量,我尝试避免使用拖放库。

更新:

这是我的设置的plunker:

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


很可能是的。但是没有查看你的代码无法确认。你能展示相关的模板和组件代码吗? - amal
@amal - 我添加了一个最小设置的 Plunker(代码共享平台) - SBB
2个回答

32

FormArray 上有几种方法,比如 removeAtinsert,可以帮助您实现目标。

template.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示例


这看起来很棒 - 我的plunk可能略有不同,因为我得到了这个错误[ts] Property 'removeAt' does not exist on type 'AbstractControl'.。当我 console.log() 我的父表单时,它的结构是这样的:https://image.ibb.co/jcg6WG/Screen_Shot_2017_09_28_at_10_34_54_AM.png我需要将其转换为其他类型才能访问它吗? - SBB
是的,我更新了 Plunker。 const rules = this.rulesForm.get('ruleData.rules') as FormArray; - yurzui
在您的屏幕截图中,FormArray被称为“Rule”,而不是“rules”。 - yurzui
谢谢,这个概念的确像我希望的那样工作,但我没有足够地检查自己的代码。我的 *ngFor 正在创建这些表单组并将它们放入数组中,但是循环遍历的是我的数据模型而不是控件。因此,尽管实际上表单控件正在在表单数据中移动,但我的 UI 没有改变。我会看看是否可以对数据模型进行更改并获得相同的结果。你做到了我所要求的,干得好。 - SBB

8

这里是“move”方法的ES6简短版本:

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示例


这种方法非常危险!它改变的是控件中的值,而不是控件的顺序。例如,如果您订阅了FormArray中的第一个控件(项),然后将其移动到第二个位置 - 订阅仍将插入到第一个位置,而不是第二个位置。 - gesiud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接