角度材质拖放-不同的对象类型

时间:2020-01-27 17:38:01

标签: angular drag-and-drop angular-material

我正在构建一个购物车,并且希望能够将商品列表中的项目拖放到购物车中并将其添加到购物车的“项目”中。这些产品更像是技术服务,因此我不想使用术语“服务...”,因此您会在模型中看到“小时”。

我能够呈现两个列表,并将“产品”拖放到购物车中。.当然,购物车包含CartItems,其中包含产品的“快照”。显然,这无法按需工作。

我的问题是:如何通过拖放操作做到这一点?

我也认识到我对这个问题的整个解决方法可能是错误的。我愿意接受任何建议。

这不是发布一堆屏幕截图和代码,而是在Stackblitz上提供指向该应用程序的链接:)

编辑:该堆栈闪电正在正常运行

drag-drop-test

模型如下:

export class Cart {
    id: string;
    title: string;
    items?: CartItem[];
}
export class CartItem {
    qty: number;
    hours: number;
    product: Product;
}
export class Product {
    id: string;
    title: string;
    dhours: number; // default hours
}

2 个答案:

答案 0 :(得分:1)

在将您的product转换为cartItem之前,将其移至其他数组。

const cartItem = [{
    qty: null,
    hours: null,
    product: event.previousContainer.data[event.previousIndex]
}]
transferArrayItem<CartItem>(cartItem,
    event.container.data,
    event.previousIndex,
    event.currentIndex);
event.previousContainer.data.splice(event.previousIndex, 1); // You will have to remove previous item yourself

更新stackblitz https://stackblitz.com/edit/github-4t79ak 我只是为了从产品列表移动到购物车,您可以尝试其他方向。

答案 1 :(得分:1)

拖放cdkdrag并不是魔术。它可以轻松地以可视方式管理object(*)的两个数组。但仅此而已:您在* ngFor中显示了两个数组,并且更改了(或不更改)拖动元素的数组。完成拖放后,Angular重新绘制了两个* ngFors

如果您查看event cdkDrapDrop,就会发现它具有属性(以及其他属性):

  1. 容器:放置物品的容器。 (container.data是与放置该项目的cdkDropList关联的数组)
  2. currentIndex:项目的当前索引。
  3. previousContainer:从中拾取物品的容器。 (previousContainer.data是与拾取项目中的cdkDropList关联的数组)
  4. previousIndex:项目在被拾取时的索引

不必使用函数transferArrayItems,例如,您可以使用

drop(event: CdkDragDrop<any>) {
    //get the data asociated to the item dragged
    const dragItem=previousContainer[previousIndex]
    //create an object using this data
    const addItem={id: dragItem.id,
                   title: dragItem.id,
                   dhours: dragItem.dhours,
    //add to the array of the data where we dropped the object
    container.data.splice(1, 0, addItem);
}

并保持与选中项目的cdkDropList关联的数组数组不变。放下对象后,Angular用数组的数据重新绘制两个“列表”

(*)已更新:好的,我实际上是在将数组称为[cdkDropListData],但是没有人禁止我们说数据是简单的字符串还是简单的对象。像

<div cdkDropList [cdkDropListData]="{name:'Name'}"
            [cdkDropListConnectedTo]="[cdkBoard]" 
            (cdkDropListDropped)="drop($event)" 
            cdkDropListSortingDisabled="true">
    <div cdkDrag>
         Drag me!
         <div *cdkDragPlaceholder></div>
    </div>
</div>

在放置事件中使previousContainer.data为对象{name:'Name'}