我在使用Angular CDK中的拖放模块时遇到了一个问题。我在具有以下CSS属性的容器div中使用它:

display: flex;
flex-wrap: wrap;

这里是flex_wrap属性,因此,如果所包含的可拖动元素不适合容器,它们将换行到第二行,依此类推。

由于拖动是水平的(cdkDropListOrientation="horizontal"),因此当所有元素都放在一行中时,此方法就很好用,但是当它们缠绕到第二行时,拖放就变成了 buggy 。我进行了以下堆栈重现以重现该错误:https://stackblitz.com/edit/angular-fytgp6

如果有人知道如何解决此问题或考虑解决此问题的方法,那将有很大的帮助!

最佳答案

这是CDK拖放的已知问题:https://github.com/angular/material2/issues/13372

本质上,您需要具有一个定义为“cdkDropListGroup”的父div,然后除了具有“cdkDrag”属性之外,还需要将每个可拖动项视为“cdkDropList”。这应该使每个项目都是其自己的容器,并且“cdkDropListGroup”指令将它们全部连接在一起。

然后,您可以在cdkDropList容器上使用一个* ngFor来为每个数组项生成一个。将[cdkDropListData] =“index”与cdkDropList一起放置,以便可以将当前拖动的索引传输到cdkDrag。使用子cdkDrag元素,可以使用[cdkDragData] =“index”获得此索引。然后,在cdkDrag子项上具有事件绑定(bind)(cdkDragEntered)=“entered($ event)”,此绑定(bind)将在您每次尝试将元素拖动到新容器之一时触发。在输入的函数内部,使用CDK中的moveItemInArray方法转移项目。

entered(event: CdkDragEnter) {
  moveItemInArray(this.items, event.item.data, event.container.data);
}
<div style="display:flex;flex-wrap:wrap" cdkDropListGroup>
  <div cdkDropList [cdkDropListData]="i" *ngFor="let item of items; let i = index;"  [style.width]="item.width || '100%'">
    <div cdkDrag [cdkDragData]="i" (cdkDragEntered)="entered($event)">
      {{item}}
    </div>
  </div>
</div>


如果这对您不起作用,那么您可以尝试使用mat-grid来控制您的布局。

<mat-grid-list cdkDropListGroup>
  <mat-grid-tile cdkDropList [cdkDropListData]="i" *ngFor="let item of items; let i = index;" [colspan]="item.cols" [rowspan]="item.rows">
    <div cdkDrag [cdkDragData]="i" (cdkDragEntered)="entered($event)">
      {{item}}
    </div>
  </mat-grid-tile>
</mat-grid-list>

10-06 02:57