Angular材质拖放-合并元素
Angular material drag and drop - merge elements
我正在构建和应用程序,其中有多个项目呈现在一组列中。
(为了演示,假设有 4 列)
我正在尝试实现将项目拖放到彼此上的功能,这将导致这两个项目合并。
打字稿数据结构
Details{
id:number;
columns:Column[];
}
Column{
id:number;
item:Item[];
}
Item{
id:number;
text:string;
}
所以我有详细信息组件:
<div fxLayout="row wrap" fxLayoutAlign="center" fxLayoutGap="5px" cdkDropListGroup>
<column *ngFor="let column of details.columns" [column]="column" fxFlex>
</column>
</div>
和列组件:
<div>
Column Header
</div>
<div cdkDropList
(cdkDropListDropped)="drop($event)"
[cdkDropListData]="column.items"
*ngFor="let item of column.items">
<item cdkDrag [item]="item" [cdkDragData]="item">
</item>
</div>
现在我只是打印它
drop(event: CdkDragDrop<Item[]>) {
console.log(event);
}
每当我现在在 drop 后打印 event
时,我确实有当前容器的详细信息并移至 ,但我需要有关我删除该元素的确切位置(在哪个 item.id 上)的信息,而不是让项目逃避默认的 cdkDragDrop 行为。之后,我将在后端等处进行合并内容的事件。
如有提示将不胜感激
我找到了解决方案。
我的同事提议传递 drop(event) 中发生事件的项目
所以最终的解决方案是:
<div cdkDropList
(cdkDropListDropped)="drop($event,item)"
[cdkDropListData]="column.items"
*ngFor="let item of column.items">
<item cdkDrag [item]="item" [cdkDragData]="item">
</item>
</div>
和处理(使用 lodash)
drop(event: CdkDragDrop<Item[]>, dropedOn: Item) {
const dragged = event.item.data;
if (dragged.id != dropedOn.id) {
dropedOn.text = dropedOn.text + "\n" + dragged.text;
if (event.previousContainer === event.container) {
_.remove(event.container.data,(item)=>item.id== dragged.id);
} else {
_.remove(event.previousContainer.data,(item)=>item.id== dragged.id);
}
}
}
已更新 stackblitz。
但是整个解决方案还是有点笨拙,很难清楚地表明要合并到哪个元素并最终移动到其他解决方案ng-drag-drop。
每个项目都是可拖放的,效果更好一些(尽管需要额外搜索项目才能将其从列中删除)
<div *ngFor="let item of column.items;" style="margin-top: 2px">
<div draggable [dragData]="item" droppable (onDrop)="onItemDrop($event,item)">
<item [item]="item"></item>
</div>
</div>
和updated stackblitz与其他解决方案
我正在构建和应用程序,其中有多个项目呈现在一组列中。 (为了演示,假设有 4 列)
我正在尝试实现将项目拖放到彼此上的功能,这将导致这两个项目合并。
打字稿数据结构
Details{
id:number;
columns:Column[];
}
Column{
id:number;
item:Item[];
}
Item{
id:number;
text:string;
}
所以我有详细信息组件:
<div fxLayout="row wrap" fxLayoutAlign="center" fxLayoutGap="5px" cdkDropListGroup>
<column *ngFor="let column of details.columns" [column]="column" fxFlex>
</column>
</div>
和列组件:
<div>
Column Header
</div>
<div cdkDropList
(cdkDropListDropped)="drop($event)"
[cdkDropListData]="column.items"
*ngFor="let item of column.items">
<item cdkDrag [item]="item" [cdkDragData]="item">
</item>
</div>
现在我只是打印它
drop(event: CdkDragDrop<Item[]>) {
console.log(event);
}
每当我现在在 drop 后打印 event
时,我确实有当前容器的详细信息并移至 ,但我需要有关我删除该元素的确切位置(在哪个 item.id 上)的信息,而不是让项目逃避默认的 cdkDragDrop 行为。之后,我将在后端等处进行合并内容的事件。
如有提示将不胜感激
我找到了解决方案。
我的同事提议传递 drop(event) 中发生事件的项目
所以最终的解决方案是:
<div cdkDropList
(cdkDropListDropped)="drop($event,item)"
[cdkDropListData]="column.items"
*ngFor="let item of column.items">
<item cdkDrag [item]="item" [cdkDragData]="item">
</item>
</div>
和处理(使用 lodash)
drop(event: CdkDragDrop<Item[]>, dropedOn: Item) {
const dragged = event.item.data;
if (dragged.id != dropedOn.id) {
dropedOn.text = dropedOn.text + "\n" + dragged.text;
if (event.previousContainer === event.container) {
_.remove(event.container.data,(item)=>item.id== dragged.id);
} else {
_.remove(event.previousContainer.data,(item)=>item.id== dragged.id);
}
}
}
已更新 stackblitz。
但是整个解决方案还是有点笨拙,很难清楚地表明要合并到哪个元素并最终移动到其他解决方案ng-drag-drop。
每个项目都是可拖放的,效果更好一些(尽管需要额外搜索项目才能将其从列中删除)
<div *ngFor="let item of column.items;" style="margin-top: 2px">
<div draggable [dragData]="item" droppable (onDrop)="onItemDrop($event,item)">
<item [item]="item"></item>
</div>
</div>
和updated stackblitz与其他解决方案