Angular 表格内单个单元格内单个元素的拖拽功能实现(单个单元格的拖拽实现也大致相同)
该功能使用了Angular提供的@angular/cdk/drag-drop模块:具体实现如下:
实现样例:
核心实现原理:
最大的连接点
1.连接各个容器:通过将想要拖拽的元素包装在具有cdkDropListGroup属性当中(cdkDropListGroup属性能将它内部的一个或多个实例连接在一起),从而实现相互关联相互拖拽的基础
容器的各个属性
2.声明容器:cdkDropList 的作用相当于声明一个存放底层要拖拽元素的一个容器(就好比如:这容器有几个可拖拽的元素,那容器也有几个可拖拽的元素,那么这两个容器就都需要加入cdkDropList属性)
3.声明所属数据集:cdkDropListData 的作用相当于声明了该内容可拖拽的容器具体属于哪一个数据集(这里我分别用cdkDropListData分别指定了两个数据集listOne和listTwo)
4.设置拖拽方式实现可随意拖拽:cdkDropListOrientation=“horizontal” 的作用是,列表拖拽方向变为了横向(默认是纵向)
5.回调方法将数据赋值过去:(cdkDropListDropped) 当你将拖拽元素松手放入容器内时的回调
拖拽元素的声明
6.声明元素可拖拽:cdkDrag 的作用是声明该元素可以拖拽
实现步骤
第一步:在.module.ts中导入注入:
//导入
import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({
//注入
imports:[DragDropModule]
})
第二步:在.component.html编写页面代码:
具体的页面代码实现:
<nz-table [nzData]="listOne" [nzFrontPagination]="false" [nzShowPagination]="false">
<thead>
<tr>
<th nzAlign="center" nzWidth="200px" nzLeft>星期1</th>
<th nzAlign="center" nzWidth="200px" nzLeft>星期2</th>
</tr>
</thead>
<!--在tbody加入属性cdkDropListGroup-->
<tbody cdkDropListGroup>
<tr>
<td>
<div
id="listOne"
cdkDropList
class="example-list"
[cdkDropListData]="listOne"
cdkDropListOrientation="horizontal"
(cdkDropListDropped)="drop($event)">
<a class="example-box" *ngFor="let item of listOne;index as i" cdkDrag >
<div class="example-custom-placeholder" *cdkDragPlaceholder> 拖拽落点位置</div>
{{"id:"+item.id}} {{"name:"+item.name}}
</a>
</div>
</td>
<td>
<div
id="listTwo"
cdkDropList
class="example-list"
cdkDropListOrientation="horizontal"
[cdkDropListData]="listTwo"
(cdkDropListDropped)="drop($event)">
<a *ngFor="let item of listTwo;index as i" class="example-box" cdkDrag>
<div class="example-custom-placeholder" *cdkDragPlaceholder> 拖拽落点位置</div>
{{"id:"+item.id}} {{"name:"+item.name}}
</a>
</div>
</td>
</tr>
</tbody>
</nz-table>
第三步:在.component.ts编写TypeScript代码:
//导入
import {moveItemInArray, transferArrayItem, CdkDragDrop} from '@angular/cdk/drag-drop';
//声明使用的两个数据集
listOne=[
{id:1,name:'少年'},
{id:2,name:'青年'},
{id:3,name:'中年'}
]
listTwo=[
{id:4,name:'早餐'},
{id:5,name:'午餐'},
{id:6,name:'晚餐'}
]
// 当你将拖拽元素松手放入容器内时的回调方法
drop(event: CdkDragDrop<string[]>) {
//重点:声明id的作用,由于拖拽event的值中时没有明确知道,哪个数据集时起点,哪个数据集时终点的,这时候在html中声明了id,event中将会出现id的值,让你能够明确来源,明确终点
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,//结束位置
);
}
}
第四步:在.component.css编写css代码:
.example-container {
width: 400px;
max-width: 100%;
margin: 0 25px 25px 0;
display: inline-block;
vertical-align: top;
}
.example-list {
min-height: 60px;
background: white;
border-radius: 4px;
overflow: hidden;
display: block;
}
.example-box {
color: rgba(0, 0, 0, 0.87);
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
cursor: move;
background: white;
font-size: 14px;
}
.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-animating {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.example-box:last-child {
border: none;
}
.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder) {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.example-custom-placeholder {
background: rgb(135, 248, 131);
border: dotted 2px #999;
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}