Angular Material 拖放 - 不同的对象类型
Angular Material Drag and Drop - Different Object Types
我正在构建一个购物车,我希望能够将产品列表中的项目拖放到购物车中,并将它们添加到购物车的 "items" 中。产品更像是技术服务,因此我不想使用术语服务...所以您会在模型中看到 "hours"。
我能够呈现这两个列表,并将产品拖放到购物车中。当然,购物车包含 CartItems,其中包含产品的 "snapshot"。显然这不能按预期工作。
我的问题是:如何使用拖放来完成此操作?
我也认识到我对这个问题的整个处理方法可能是错误的。我愿意接受任何建议。
而不是 post 一堆屏幕截图和代码,这里是应用程序的 link :) 在 Stackblitz 上:
编辑:这个 stackblitz 运行正常
型号如下:
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
}
您需要先将 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
我只是为了从产品列表移动到购物车项目,你可以尝试其他方向。
cdk 拖放并不神奇。它使以可视化方式轻松管理两个对象 (*) 数组。但仅此而已:您有两个数组显示在 *ngFor 中,并且您更改(或不更改)拖动元素的数组。完成拖放后,Angular 重新绘制两个 *ngFors
如果您查看 event cdkDrapDrop,您会发现它具有如下属性(以及其他属性):
- 容器:放置物品的容器。 (container.data 是与 中的 cdkDropList 关联的数组,该项目已被删除)
- currentIndex:项目的当前索引。
- previousContainer:从中拾取项目的容器。 (previousContainer.data 是与 中的 cdkDropList 关联的数组,该项目已被拾取)
- 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 用数组
的数据重新绘制两个 "list"
(*)更新: 好吧,我实际上是在谈论数组作为 [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'}
我正在构建一个购物车,我希望能够将产品列表中的项目拖放到购物车中,并将它们添加到购物车的 "items" 中。产品更像是技术服务,因此我不想使用术语服务...所以您会在模型中看到 "hours"。
我能够呈现这两个列表,并将产品拖放到购物车中。当然,购物车包含 CartItems,其中包含产品的 "snapshot"。显然这不能按预期工作。
我的问题是:如何使用拖放来完成此操作?
我也认识到我对这个问题的整个处理方法可能是错误的。我愿意接受任何建议。
而不是 post 一堆屏幕截图和代码,这里是应用程序的 link :) 在 Stackblitz 上:
编辑:这个 stackblitz 运行正常
型号如下:
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
}
您需要先将 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 我只是为了从产品列表移动到购物车项目,你可以尝试其他方向。
cdk 拖放并不神奇。它使以可视化方式轻松管理两个对象 (*) 数组。但仅此而已:您有两个数组显示在 *ngFor 中,并且您更改(或不更改)拖动元素的数组。完成拖放后,Angular 重新绘制两个 *ngFors
如果您查看 event cdkDrapDrop,您会发现它具有如下属性(以及其他属性):
- 容器:放置物品的容器。 (container.data 是与 中的 cdkDropList 关联的数组,该项目已被删除)
- currentIndex:项目的当前索引。
- previousContainer:从中拾取项目的容器。 (previousContainer.data 是与 中的 cdkDropList 关联的数组,该项目已被拾取)
- 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 用数组
的数据重新绘制两个 "list"(*)更新: 好吧,我实际上是在谈论数组作为 [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'}