Angular CDK 拖放:不要移动源项目

Yas*_*ouh 19 drag-and-drop angular angular-cdk

我正在尝试实现一个编辑器,可以在其中拖动项目以将其添加到主要内容中,问题是当我拖出源项目容器时,源项目总是被破坏。

有没有办法强制源项目保持原样,同时仍然可以拖放项目?基本上,我想要一个复制行为而不是移动行为。

我已经看到了与我想要实现的基本目标相对应的其他问题,但它们都没有真正帮助我,因为问题更多地是关于如何在技术上完成复制项目的同时我想知道我如何实现这种行为在 UI 中,因为查看项目是否刚刚消失非常令人困惑。

小智 18

代替

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
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

drop(event: any) {
  if (event.previousContainer === event.container) {
    moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
  } else {
    copyArrayItem(
      event.previousContainer.data,
      event.container.data,
      event.previousIndex,
      event.currentIndex
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢这个解决方案。但是,通过这种行为,正在从中移动元素的列表上存在样式问题。它会改变列表,因为它看起来像是删除然后添加列表中的元素以进行复制操作。请参阅此 stackblitz 链接 - https://stackblitz.com/edit/angular-g5uzys?file=app%2Fcdk-drag-drop-connected-sorting-example.ts (7认同)

TRI*_*EMS 6

进口import {copyArrayItem} from '@angular/cdk/drag-drop';

transferArrayItem用。。。来代替copyArrayItem


Vik*_*ari 6

上面的所有解决方案都很好,但是在删除元素后克隆会发生一个问题,所以我进行了 git 转换并找到了下面的解决方案

风格

.drag-container {
    width: 400px;
    max-width: 100%;
    margin: 0 25px 25px 0;
    display: inline-block;
    vertical-align: top;
}

.drag-list {
    border: solid 1px #ccc;
    min-height: 60px;
    background: white;
    border-radius: 4px;
    overflow: hidden;
    display: block;
}

.drag-box {
    padding: 20px 10px;
    border-bottom: solid 1px #ccc;
    color: rgba(0, 0, 0, 0.87);
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    box-sizing: border-box;
    cursor: move;
    background: white;
    font-size: 14px;
}

.cdk-drag-preview {
    box-sizing: border-box;
    border-radius: 4px;
    box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
        0 8px 10px 1px rgba(0, 0, 0, 0.14),
        0 3px 14px 2px rgba(0, 0, 0, 0.12);
}

.cdk-drag-placeholder {
    opacity: 0;
}

.cdk-drag-animating {
    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}

.drag-box:last-child {
    border: none;
}

.drag-list.cdk-drop-list-dragging .drag-box:not(.cdk-drag-placeholder) {
    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
Run Code Online (Sandbox Code Playgroud)

打字稿

menu: any = [
    { title: 'pork', price: 12, id: 1 },
    { title: 'duck', price: 12, id: 2 },
    { title: 'chicken', price: 12, id: 3 },
    { title: 'beef', price: 12, id: 4 },
    { title: 'soup', price: 12, id: 5 },
  ];

  table: any = [];



  drop(event: any) {
    if (event.previousContainer !== event.container) {
      copyArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    } else {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    }
    if (event.previousContainer.data) {
      this.menu = this.menu.filter((f: any) => !f.temp);
    }
  }



  exited(event: any) {
    const currentIdx = event.container.data.findIndex(
      (f: any) => f.id === event.item.data.id
    );
    this.menu.splice(currentIdx + 1, 0, {
      ...event.item.data,
      temp: true,
    });
  }
  entered() {
    this.menu = this.menu.filter((f: any) => !f.temp);
  }
Run Code Online (Sandbox Code Playgroud)

超文本标记语言

<div cdkDropListGroup>
            <div class="drag-container">
                <h2>To do</h2>
                <div class="drag-list" cdkDropList #menuList="cdkDropList" [cdkDropListData]="menu" cdkDropListSortingDisabled [cdkDropListConnectedTo]="[tableList]" (cdkDropListDropped)="drop($event)" (cdkDropListExited)="exited($event)" (cdkDropListEntered)="entered()">
                    <div class="drag-box" *ngFor="let item of menu" cdkDrag [cdkDragData]="item">{{item.title}}</div>
                </div>
            </div>
            <div class="drag-container">
                <h2>Done</h2>
                <div class="drag-list" cdkDropList #tableList="cdkDropList" [cdkDropListData]="table" (cdkDropListDropped)="drop($event)">
                    <div class="drag-box" *ngFor="let item of table; let idx = index" cdkDrag>{{item.title}}</div>
                </div>
            </div>
</div>
Run Code Online (Sandbox Code Playgroud)

来源 1:stackblitz

来源2:github

  • +1 这个解决方案更好地回答了原来的问题。使用 Exited 和 Entered 事件可以让用户体验更加流畅。 (2认同)