Mar*_*der 15 drag-and-drop angular-material angular angular-cdk
我使用 CDK Material Drag and Drop 实用程序创建一个启用拖放功能的表单编辑器。
它工作正常,但cdkDropList在 a 中嵌套 acdkDropListGroup不起作用。我无法将任何内容拖到嵌套的下拉列表容器中。
<div class="container">
<div class="row" cdkDropListGroup>
<div class="col-2">
<div id="toolbox" cdkDropList>
...
</div>
</div>
<div class="col-10">
<div id="formContainer" cdkDropList>
...
<div class="row">
<div class="col-md-6" cdkDropList>
... column 1 content
</div>
<div class="col-md-6" cdkDropList>
... column 1 content
</div>
</div>
</div>
</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
Mar*_*der 24
我花了一些时间,但由于该帖子的提示,我终于找到了解决方案:
问题是cdkDropListGroup不支持嵌套下拉列表。您需要将下拉列表与[cdkDropListConnectedTo]绑定连接起来。
但是,如果您仅将列表连接到数组以进行[cdkDropListConnectedTo]绑定,则列表顺序会对放置行为产生影响。此外,在嵌套下拉列表中排序将不起作用。
为了避免这些问题,您需要创建一个在拖动时查找正确的服务cdkDropList。
export class DragDropService {
dropLists: CdkDropList[] = [];
currentHoverDropListId?: string;
constructor(@Inject(DOCUMENT) private document: Document) {}
public register(dropList: CdkDropList) {
this.dropLists.push(dropList);
}
dragMoved(event: CdkDragMove<IFormControl>) {
let elementFromPoint = this.document.elementFromPoint(
event.pointerPosition.x,
event.pointerPosition.y
);
if (!elementFromPoint) {
this.currentHoverDropListId = undefined;
return;
}
let dropList = elementFromPoint.classList.contains('cdk-drop-list')
? elementFromPoint
: elementFromPoint.closest('.cdk-drop-list');
if (!dropList) {
this.currentHoverDropListId = undefined;
return;
}
this.currentHoverDropListId = dropList.id;
}
dragReleased(event: CdkDragRelease) {
this.currentHoverDropListId = undefined;
}
}
Run Code Online (Sandbox Code Playgroud)
register将新的下拉列表添加到dropList每个 所使用的数组中cdkDropList。
dragMovedcdkDropList确定鼠标指针下方的正确位置。
最好的事情是创建一个自己的组件来保存cdkDropList.
以下组件仅用于简单和演示目的。您不应直接使用服务属性。
<div
*ngIf="container"
cdkDropList
[cdkDropListData]="container.controls"
[cdkDropListConnectedTo]="dragDropService.dropLists"
[cdkDropListEnterPredicate]="allowDropPredicate"
(cdkDropListDropped)="dropped($event)"
>
<div
*ngFor="let item of container.controls"
cdkDrag
[cdkDragData]="item"
(cdkDragMoved)="dragMoved($event)"
(cdkDragReleased)="dragReleased($event)"
>
Drag Content
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
export class FormContainerComponent implements OnInit, AfterViewInit {
@ViewChild(CdkDropList) dropList?: CdkDropList;
@Input() container: IFormContainer | undefined;
allowDropPredicate = (drag: CdkDrag, drop: CdkDropList) => {
return this.isDropAllowed(drag, drop);
};
constructor(
public dragDropService: DragDropService
) {}
ngOnInit(): void {}
ngAfterViewInit(): void {
if (this.dropList) {
this.dragDropService.register(this.dropList);
}
}
dropped(event: CdkDragDrop<IFormControl[]>) {
// Your drop logic
}
isDropAllowed(drag: CdkDrag, drop: CdkDropList) {
if (this.dragDropService.currentHoverDropListId == null) {
return true;
}
return drop.id === this.dragDropService.currentHoverDropListId;
}
dragMoved(event: CdkDragMove<IFormControl>) {
this.dragDropService.dragMoved(event);
}
dragReleased(event: CdkDragRelease) {
this.dragDropService.dragReleased(event);
}
}
Run Code Online (Sandbox Code Playgroud)
cdkDrag移动时,dragMoved确定正确的cdkDropListcdkDrag被释放时,重置确定的cdkDropListisDropAllowed针对[cdkDropListEnterPredicate]="allowDropPredicate"cdkDropList
cdkDropList正确选项:)您可以在此处找到示例代码:https ://github.com/MarcusKaseder/cdk-drag-and-drop-form
| 归档时间: |
|
| 查看次数: |
12490 次 |
| 最近记录: |