我尝试使用 cdkDrag 拖放项目(在任何地方自由拖放),并且它无需 cdkDropList 即可工作。我可以在两个容器之间交换项目(可用服务<=> Dropbox 容器)。但是,当尝试使用 Angular、Angular 材质拖放将 cdkDropList 作为父容器时,Dropbox 容器内的自由拖放功能无法正常工作。
预期结果: 用户可以将项目拖放到 cdkDropList Dropbox 容器内的任何位置。
Stackblitz 链接
https://stackblitz.com/edit/stackblitz-starters-djbrtx?file=src%2Fmain.ts
我尝试了以下代码流程
Html模板
<div class="container">
<section class="service-container">
<div class="row" cdkDropListGroup>
<div class="col-2 available-service text-center">
<h4 class="pt-3">Available Services</h4>
<div
cdkDropList
[cdkDropListData]="todo"
class="service-list"
(cdkDropListDropped)="drop($event)">
<div class="service-box" *ngFor="let item of todo; let i = index"
cdkDrag
>
{{item}}
</div>
</div>
</div>
<div class="col">
<h2>Dropbox Container</h2>
<div class="service-boundary"
cdkDropList
[cdkDropListData]="done"
(cdkDropListDropped)="drop($event)"
>
<div *ngFor="let item of done; let i = index" class="service-box"
cdkDrag
>
<strong>
{{item}}
</strong>
</div>
</div>
</div>
</div>
</section>
</div>
ts 文件
import { ChangeDetectorRef, Component } from '@angular/core';
import {
CdkDragDrop,
moveItemInArray,
transferArrayItem,
} from '@angular/cdk/drag-drop';
import { BehaviorSubject } from 'rxjs';
@Component({
selector: 'app-workflow-dashboard',
templateUrl: './workflow-dashboard.component.html',
styleUrls: ['./workflow-dashboard.component.scss']
})
export class WorkflowDashboardComponent {
todo:any = ['One', 'Two', 'Three'];
done: any = ['Four'];
constructor(private changeDetectionRef: ChangeDetectorRef) {}
drop(event: CdkDragDrop<any[]>) {
if (event.previousContainer === event.container) {
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
} else {
transferArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex,
);
}
}
}
SCSS
.service-container {
border: solid 1px #ccc;
margin-bottom: 25px;
.available-service {
border: solid 1px #ccc;
margin: 15px 0 15px 25px;
}
}
.service-list {
min-height: 90%;
background: white;
border-radius: 4px;
overflow: hidden;
display: block;
position: relative;
}
.service-box {
margin: 7px 7px;
width: 150px;
height: 50px;
border: solid 1px #ccc;
color: rgba(0, 0, 0, 0.87);
cursor: move;
display: inline-flex;
justify-content: center;
align-items: center;
text-align: center;
background: #fff;
border-radius: 4px;
margin-right: 25px;
position: relative;
z-index: 1;
box-sizing: border-box;
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);
&: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);
}
}
.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: 0;
}
.cdk-drag-animating {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.service-boundary {
height: 100%;
}
用
cdkDropList
似乎不可能。它的 API 支持排序:https://material.angular.io/cdk/drag-drop/api#CdkDropList。如果他们允许自由拖放 - 排序将不起作用,因为不可能订购物品。
但是,您仍然可以在没有
cdkDropList
的情况下实现它。为此,您可以使用 (cdkDragMoved)
指令的 (cdkDragEnded)
和 cdkDrag
事件。然后就可以从cdkDragEnded
获取x和y或者鼠标事件来实现手动拖放处理。
顺便说一句,
CdkDrag
还有很多其他有用的输出可用于自定义d'n'd实现:https://material.angular.io/cdk/drag-drop/api#CdkDrag