我正在尝试将 FormArray 与 cdkDropList 结合使用。但是,一旦我添加相应的 FormGroup,该组中的 cdkDrag 就会停止工作。为简单起见,我在此处删除了任何其他事件,例如按钮的单击事件等。
所以这有效:
<div cdkDropList cdkDropListOrientation="horizontal" style="display: flex;">
<ng-container *ngFor="let group of formArray.value; let i = index" formArrayName="myFormArray">
<div cdkDrag>
<div cdkDragHandle style="padding: 1em; margin: 1em;background: red;">{{i}}</div>
</div>
</ng-container>
</div>
这不是:
<div cdkDropList cdkDropListOrientation="horizontal" style="display: flex;">
<ng-container *ngFor="let group of formArray.value; let i = index" formArrayName="compositeContent">
<div [formGroupName]="i" cdkDrag>
<div cdkDragHandle style="padding: 1em; margin: 1em;background: red;">{{i}}</div>
</div>
</ng-container>
</div>
这也不是:
<div cdkDropList cdkDropListOrientation="horizontal" style="display: flex;">
<ng-container *ngFor="let group of formArray.value; let i = index" formArrayName="compositeContent">
<div cdkDrag>
<div cdkDragHandle style="padding: 1em; margin: 1em;background: red;">{{i}}</div>
<div [formGroupName]="i"></div>
</div>
</ng-container>
</div>
这是 formArray getter:
get formArray(): FormArray {
return this.form.controls["formArray"] as FormArray;
}
当从我的 API 将现有数据添加到 FormArray 时,这就是我创建新 formArray 元素的方式:
addElement(data): void {
this.formArray.insert(this.formArray.length, this.getNewElementFormGroup(data));
}
getNewElementFormGroup(data): FormGroup {
return new FormGroup({...});
}
这是一个stackblitz。将 [formGroupName]="i" 添加到 cdkDrag div 以重现错误。
formArrayName
必须是*ngFor
上方的顶部元素。
主要问题是,您需要在控件而不是值上运行 for 循环,这解决了问题。
下面的工作示例!
<form [formGroup]="form">
<div
cdkDropList
cdkDropListOrientation="horizontal"
style="display: flex;"
(cdkDropListDropped)="drop($event)"
formArrayName="myFormArray"
>
<ng-container
*ngFor="
let formGroup of formArray.controls;
trackBy: trackBy;
let i = index
"
>
<div cdkDrag [formGroupName]="i">
<div cdkDragHandle style="padding: 1em; margin: 1em;background: red;">
{{ formGroup?.controls?.control?.value }}
</div>
</div>
</ng-container>
</div>
</form>
ts
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { Component } from '@angular/core';
import {
FormBuilder,
FormGroup,
FormArray,
FormControl,
Validators,
} from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
form: FormGroup;
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.form = new FormGroup({
myFormArray: new FormArray([]),
});
this.addElement(1);
this.addElement(2);
this.addElement(3);
}
get formArray(): FormArray {
return this.form.controls['myFormArray'] as FormArray;
}
addElement(data): void {
this.formArray.insert(
this.formArray.length,
this.getNewElementFormGroup(data)
);
}
trackBy(i, item) {
return item;
}
getNewElementFormGroup(data): FormGroup {
return new FormGroup({
control: new FormControl(data, []),
});
}
drop(event: CdkDragDrop<string[]>) {
moveItemInArray(
this.formArray.controls,
event.previousIndex,
event.currentIndex
);
}
}