【问题标题】:CDK Drag Drop does not correctly change the position of imagesCDK 拖放无法正确更改图像的位置
【发布时间】:2020-06-27 19:41:47
【问题描述】:

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

我的问题是图像的交换并不总是正确发生,有时我将第一张图像与第二张交换并且这种交换不会发生。

我怎样才能让这个功能齐全,水平和垂直?

有没有一种方法只有在图像存储在 mdc-image-list - with-text-protection 类中时才能开始拖动?

谢谢!

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
      );
    }
  }

【问题讨论】:

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


    【解决方案1】:

    我发现允许在网格中拖放的唯一方法是网格的每个元素都是一个 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;
      }
    

    是的!我们不强制使用 drop 来展示示例。想想我们唯一想要的就是改变一个数组。

    还有一件事要做,让"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

    【讨论】:

    • 嘿,我在stackblitz.com/edit/…找到了另一个惊人的例子,来自c3rber,别忘了检查它(github中的讨论是github.com/angular/components/issues/13372
    • 有没有办法使用拖放 cdk 将图像拖动到“放置”区域,当放置该图像时,我可以从该放置的图像中提取数据?
    • 如果你能帮助我,我已经更新了链接。如有必要,我可以创建一个新问题。
    • 使用@angular/cdk/drag-drop,你有两个cdkList,一个是带有[cdkDropListConnectedTo]="[dropZone]"的图像列表,另一个是你要放置图像的div:&lt;div class="card selectionCard" cdkDropList #dropZone="cdkDropList" (cdkDropListDropped)="dropOnZone($event)" [cdkDropListData]="null"&gt;see也需要在放置区添加一个 ckdDrag 。在 dropOnZone 函数中,您可以在 event.previousContainer.data[event.previousIndex] 中拖动项目的“数据”,请参阅 stackblitz.com/edit/…
    猜你喜欢
    • 2020-12-17
    • 1970-01-01
    • 2020-07-15
    • 2021-08-14
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    • 2023-03-23
    • 2019-05-09
    相关资源
    最近更新 更多