【问题标题】:Angular Material Drag and Drop - Different Object Types角度材质拖放 - 不同的对象类型
【发布时间】:2020-01-27 17:38:01
【问题描述】:

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

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

我的问题是:如何使用拖放功能做到这一点?

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

与其发布一堆屏幕截图和代码,不如在 Stackblitz 上发布应用程序的链接 :):

编辑:这个 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
}

【问题讨论】:

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


    【解决方案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
    

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

    【讨论】:

    • 我尝试将购物车项目移至产品列表。它似乎正在工作。但是,我不认为我的 if..then 是最优雅的解决方案。
    【解决方案2】:

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

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

    1. container:物品被丢弃的容器。 (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'}

    【讨论】:

      猜你喜欢
      • 2019-06-02
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      • 2021-03-20
      • 2019-06-14
      • 1970-01-01
      • 2022-12-25
      相关资源
      最近更新 更多