CDK拖放不会正确更改图像的位置

时间:2020-03-16 17:10:33

标签: angular typescript angular-material angular-cdk angular-cdk-drag-drop

我创建了一个图片库,并打算更改它们之间的位置。为此,我使用了拖放CDK库。

我的问题是图像交换并不总是正确发生,有时我将第一个图像与第二个交换,而这种交换却没有发生。

如何在水平和垂直方向上都具有这种功能?

只有在图像存储在具有文本保护类的mdc-image-list中时,拖动才能开始吗?

谢谢!

DEMO

.HTML

  <ul class="mdc-image-list my-image-list" style="padding-left: 10px;padding-right: 10px;" cdkDropList [cdkDropListData]="data"
           (cdkDropListDropped)="drop($event)">
    <ng-container *ngFor="let product of data; let  j = index;">
      <li class="mdc-image-list__item" cdkDrag>
        <div class="mdc-image-list__image-aspect-container">
          <ng-container *ngIf="product.image == null; else productImage">
            <img src="" class="mdc-image-list__image imagenotfound">
          </ng-container>
          <ng-template #productImage>
            <img [src]="product.image" class="mdc-image-list__image">
          </ng-template>
        </div>
        <div class="mdc-image-list--with-text-protection">
        <div class="mdc-image-list__supporting mdc-image-list__supporting">
        <span class="mdc-image-list__label">{{product.name}}</span>
        </div>
        </div>
      </li>
    </ng-container>
  </ul>

.ts

    drop(event: CdkDragDrop<string[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    }
  }

Images

1 个答案:

答案 0 :(得分:2)

我发现允许在网格中拖放的唯一方法是网格的每个元素都是一个cdkDropList。

优势:拖动时元素不会移动

好吧,因为每个cdkDropList的数据都将是一个对象,我们要传输的数据和索引

[cdkDropListData]="{item:product,index:j}"

因此,我们的函数dropEvent根据此值更改数组数据

  drop(event: CdkDragDrop<any>) {
    this.data[event.previousContainer.data.index]={...event.container.data.item}
    this.data[event.container.data.index]={...event.previousContainer.data.item}
    event.currentIndex=0;
  }

是的!我们并没有强迫使用下降作为示例。认为我们唯一需要的就是更改数组。

还有另一件事要做,使“ dragPlaceHolder变成一个空的div

<div cdkDrag>
     ....
    <div  *cdkDragPlaceholder></div>
</div>

嗯,html有点复杂,因为自己的mdc-image-list很复杂。重要的是,所有cdkDropList必须包含在div ckdDropListGroup中

<div cdkDropListGroup>

    <ul class="mdc-image-list my-image-list" style="padding-left: 10px;padding-right: 10px;">
        <ng-container *ngFor="let product of data; let  j = index;">
            <li class="mdc-image-list__item" cdkDropList [cdkDropListData]="{item:product,index:j}"
                cdkDropListOrientation="horizontal" (cdkDropListDropped)="drop($event)">
                <div cdkDrag>
                    <div class="mdc-image-list__image-aspect-container">
                        <ng-container *ngIf="product.image == null; else productImage">
                            <img src="" class="mdc-image-list__image imagenotfound">
          </ng-container>
                            <ng-template #productImage>
                                <img [src]="product.image" class="mdc-image-list__image">
          </ng-template>
                    </div>
                    <div class="mdc-image-list--with-text-protection">
                        <div class="mdc-image-list__supporting mdc-image-list__supporting">
                            <span class="mdc-image-list__label">{{product.name}}</span>
                        </div>
                    </div>
                    <div class="example-custom-placeholder" *cdkDragPlaceholder></div>
                </div>
            </li>
        </ng-container>
    </ul>
</div>

这里是your forked stackblitz

注意:如果有人想要一个更简单的示例,请参见此another stackblitz