[英]Angular FormArray contents order
Hya,嗨,
I have the below setup:我有以下设置:
App.Component.Ts contents 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());
}
Extra Model额外 Model
export class Extra {
name: string = '';
description: string = '';
}
Now lets say i add 4 new Extras, the array would look as follows:现在假设我添加了 4 个新的 Extras,数组将如下所示:
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"
I want to be able to programmatically change the order of the 4 items listed.我希望能够以编程方式更改列出的 4 个项目的顺序。 Say i click up button next to "Slick Rims", it will swap positions with "Rainbow Paint Job" item.假设我单击“Slick Rims”旁边的向上按钮,它将与“Rainbow Paint Job”项目交换位置。 If i press it again it will swap positions with "Clearshield" with result as follows.如果我再次按下它,它将与“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"
Same principle if i press the down button for the entry.如果我按下条目的向下按钮,原理相同。
Any ideas how to achieve this, its doing my head in on how to achieve this with a FormArray.任何想法如何实现这一点,我都在思考如何使用 FormArray 实现这一点。
Assuming your form array looks like this in HTML: 假设您的表单数组在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>
you can create moveUp
and moveDown
functions to swap values at indexes (i-1, i) or (i, i+1) if it is possible 您可以创建moveUp
和moveDown
函数以在索引(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 function: 交换功能:
swap(arr: any[], index1: number, index2: number): any[] {
arr = [...arr];
const temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
return arr;
}
demo: https://stackblitz.com/edit/angular-bhcdcf 演示: https : //stackblitz.com/edit/angular-bhcdcf
EDIT: Actually we can simplify that to single function 编辑:实际上,我们可以将其简化为单个功能
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);
}
}
which would be called with appropriate indexes 将使用适当的索引来调用
<button (click)="swap(i - 1, i)"> UP </button>
<button (click)="swap(i, i + 1)"> DOWN </button>
demo: https://stackblitz.com/edit/angular-9gifvd 演示: https : //stackblitz.com/edit/angular-9gifvd
EDIT 2 by Aeseir: Aeseir编辑2:
Further simplification and following DRY principle (at least attempting to): 进一步简化并遵循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);
}
If you have FormGroup in FormArray and FormGroup also has FormArray, you'll want to just swap them around.如果您在 FormArray 中有 FormGroup 并且 FormGroup 也有 FormArray,那么您只需交换它们即可。 The next example works for me:下一个示例适用于我:
import { FormArray } from '@angular/forms';
const swap = <T>(items: T[], a: number, b: number): T[] => {
switch (true) {
case a < 0:
case b < 0:
case a > items.length - 1:
case b > items.length - 1:
throw new Error('Undefined swap index');
}
return items.map((_, i) => {
switch (i) {
case a:
return items[b];
case b:
return items[a];
default:
return items[i];
}
});
};
export const swapFormArray = <T extends FormArray>(formArray: T, a: number, b: number): void => {
formArray.controls = swap(formArray.controls, a, b);
formArray.updateValueAndValidity();
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.