2

我有一个基于这个 stackblitz 的组件:https ://stackblitz.com/edit/angular-5mf7hl

当我尝试交换列表中的元素时出现问题。我希望数组项交换位置。在上面的 stackblitz 示例中,当目标 listItem 被 sourceItem 替换时,它会在列表中的预览期间被向前或向后推送。通过在这个 StackOverflow 问题中从 Shinjo 借用一些代码,我设法让它们交换位置:Angular 7 drag Drop swapping elements

交换本身很完美,但是,当我将一个列表项拖到另一个列表项上时,预览不正确。当您释放时,它会自行更正,并且 listItem 会出现在数组中的正确位置。我想要的是,在放开拖动的项目之前,源列表项和目标列表项在预览期间交换位置。您可以查看上面的 stackblitz 以直观地看到问题。

应用组件.ts

import { Component, NgModule, ViewChild } from '@angular/core';
import {
  CdkDrag,
  CdkDragStart,
  CdkDropList, CdkDropListContainer, CdkDropListGroup,
  moveItemInArray
} from "@angular/cdk/drag-drop";

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
@ViewChild(CdkDropListGroup) listGroup: CdkDropListGroup<CdkDropList>;
@ViewChild(CdkDropList) placeholder: CdkDropList;

public items: Array<number> = [1, 2, 3, 4, 5, 6, 7, 8, 9];

public target: CdkDropList;
public targetIndex: number;
public source: CdkDropListContainer;
public sourceIndex: number;

constructor() {
  this.target = null;
  this.source = null;
}

ngAfterViewInit() {
  let phElement = this.placeholder.element.nativeElement;

  phElement.style.display = 'none';
  phElement.parentNode.removeChild(phElement);
}

drop() {
  if (!this.target)
    return;

  let phElement = this.placeholder.element.nativeElement;
  let parent = phElement.parentNode;

  phElement.style.display = 'none';

  parent.removeChild(phElement);
  parent.appendChild(phElement);
  parent.insertBefore(this.source.element.nativeElement, 
  parent.children[this.sourceIndex]);

  this.target = null;
  this.source = null;

  if (this.sourceIndex != this.targetIndex) {
    let oldtarget = this.items[this.sourceIndex];
    this.items[this.sourceIndex] = this.items[this.targetIndex];
    this.items[this.targetIndex] = oldtarget;
  }
}

enter = (drag: CdkDrag, drop: CdkDropList) => {
  if (drop == this.placeholder)
  return true;

  let phElement = this.placeholder.element.nativeElement;
  let dropElement = drop.element.nativeElement;

  let dragIndex = __indexOf(dropElement.parentNode.children, 
  drag.dropContainer.element.nativeElement);
  let dropIndex = __indexOf(dropElement.parentNode.children, dropElement);

  if (!this.source) {
    this.sourceIndex = dragIndex;
    this.source = drag.dropContainer;

    let sourceElement = this.source.element.nativeElement;
    phElement.style.width = sourceElement.clientWidth + 'px';
    phElement.style.height = sourceElement.clientHeight + 'px';

    sourceElement.parentNode.removeChild(sourceElement);
  }

  this.targetIndex = dropIndex;
  this.target = drop;

  phElement.style.display = '';
  dropElement.parentNode.insertBefore(phElement, (dragIndex < dropIndex)
  ? dropElement.nextSibling : dropElement);

  this.source.start();
  this.placeholder.enter(drag, drag.element.nativeElement.offsetLeft, 
  drag.element.nativeElement.offsetTop);

  return false;
  }
}
function __indexOf(collection, node) {
  return Array.prototype.indexOf.call(collection, node);
};

App.component.html

<div class="example-container" cdkDropListGroup>
  <div cdkDropList [cdkDropListEnterPredicate]="enter" (cdkDropListDropped)="drop()" #placeholder></div>
  <div cdkDropList *ngFor="let item of items"
       [cdkDropListEnterPredicate]="enter" (cdkDropListDropped)="drop()">
    <div cdkDrag class="example-box">{{item}}</div>
  </div>
</div> 

App.component.css

.example-list {
  list-style-type: none;
  padding: 0;
}

.example-list li {
  display: table-cell;
  padding: 4px;
}

.example-container {
  display: flex;
  flex-wrap: wrap;
  min-width: 600px;
  max-width: 900px;
}

.example-box {
  width: 200px;
  height: 200px;
  border: solid 1px #ccc;
  font-size: 30pt;
  font-weight: bold;
  color: rgba(0, 0, 0, 0.87);
  cursor: move;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  background: #fff;
  border-radius: 4px;
  position: relative;
  z-index: 1;
  transition: box-shadow 200ms cubic-bezier(0, 0, 0.2, 1);
  box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
  0 2px 2px 0 rgba(0, 0, 0, 0.14),
  0 1px 5px 0 rgba(0, 0, 0, 0.12);
}

.example-box:active {
  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);
  opacity: .6;
}

.cdk-drop-list {
  display: flex;
  padding-right: 10px;
  padding-bottom: 10px;
}

.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: .3;
}

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

0 回答 0