Angular FormArray内容顺序

时间:2018-03-14 09:06:04

标签: javascript angular typescript

Hya星,

我有以下设置:

App.Component.Ts内容

carForm: FormGroup;

constructor(
    private fb: FormBuilder
  ) { 
    this.carForm= this.fb.group({
      name: '',
      type: '',
      extras: this.fb.array([])
    });
  }

get carExtras(): FormArray {
    return this.carForm.get('extras') as FormArray;
  }

addNewExtra() {
   this.carExtras.push(this.fb.group(new Extra());
}

额外型号

export class Extra {
name: string = '';
description: string = '';
}

现在假设我添加4个新的额外内容,数组看起来如下:

1. name = "Phantom Wheels", description = "Big dark wheels coz driver is overcompensating"
2. name = "Clearshield", description = "Simple tint that we overcharge customers"
3. name = "Rainbow Paint Job", description = "Leftover random paints mixed and thrown onto car"
4. name = "Slick Rims", description = "Major overcompensation"

我希望能够以编程方式更改列出的4个项目的顺序。 假设我点击了" Slick Rims"旁边的按钮,它将与" Rainbow Paint Job"交换位置。项目。如果我再次按它,​​它将与" Clearshield"交换位置。结果如下。

1. name = "Phantom Wheels", description = "Big dark wheels coz driver is overcompensating"
2. name = "Slick Rims", description = "Major overcompensation"
3. name = "Clearshield", description = "Simple tint that we overcharge customers"
4. name = "Rainbow Paint Job", description = "Leftover random paints mixed and thrown onto car"

如果我按下输入的向下按钮,原则相同。

任何想法如何实现这一目标,它都是如何通过FormArray实现这一目标。

1 个答案:

答案 0 :(得分:5)

假设您的表单数组在HTML中显示如下:

  <div formArrayName="extras">
    extras:
    <div *ngFor="let extra of carForm.get('extras').controls; let i=index" [formGroupName]="i" >
      <input formControlName="name">
      <input formControlName="description">
      <button (click)="moveUp(i)"> UP </button>
      <button (click)="moveDown(i)"> DOWN </button>
    </div>
  </div>

如果可能,您可以创建moveUpmoveDown函数来交换索引(i-1,i)或(i,i + 1)的值

  moveUp(index: number) {
    if (index > 0) {
          const extrasFormArray = this.carForm.get('extras') as FormArray;
          const extras = extrasFormArray.value;
          const newExtras = this.swap(extras, index - 1, index); 
          extrasFormArray.setValue(newExtras);
    }
  }

  moveDown(index: number) {
    const extrasFormArray = this.carForm.get('extras') as FormArray;
    const extras = extrasFormArray.value;
    if (index < extras.length - 1) {
      const newExtras = this.swap(extras, index, index + 1); 
      extrasFormArray.setValue(newExtras);
    }
  }

交换功能:

  swap(arr: any[], index1: number, index2: number): any[] {
    arr = [...arr];
    const temp = arr[index1];
    arr[index1] = arr[index2];
    arr[index2] = temp;
    return arr;
  }

演示:https://stackblitz.com/edit/angular-bhcdcf

编辑:实际上我们可以将其简化为单一功能

  swap(index1: number, index2: number) {
    const extrasFormArray = this.carForm.get('extras') as FormArray;
    const extras = [...extrasFormArray.value];
    if (index2 > 0 && index1 < extras.length - 1) {
      [extras[index1], extras[index2]] = [extras[index2], extras[index1]];
      extrasFormArray.setValue(extras);
    }
  }

将使用适当的索引调用

  <button (click)="swap(i - 1, i)"> UP </button>
  <button (click)="swap(i, i + 1)"> DOWN </button>

演示:https://stackblitz.com/edit/angular-9gifvd

Aeseir的编辑2:

进一步简化并遵循DRY原则(至少尝试):

get extras(): FormArray {
  return this.carForm.get('extras') as FormArray;
}


moveUp(index: number) {
  var extraTmp = this.extras.at(index);
  this.removeExtra(index);
  this.extras.insert(index-1, extraTmp);
}

moveDown(index: number) {
  var extraTmp = this.extras.at(index-1);
  this.removeExtra(index-1);
  this.extras.insert(index, extraTmp);
}

removeExtra(index: number) {
  this.extras.removeAt(index);
}