拖放功能实践:Angular 7 CDK 拖拽排序完整指南
Angular 7 CDK 中新增的拖放模块,让列表元素的拖动与排序变得非常直观。本文将用一个完整的实战示例,逐步拆解拖放功能的实现全过程。第一步非常简单:安装所需的依赖包。
npm install @angular/cdk --sa ve

导入拖放模块到 app.module.ts
安装完成后,按照 Angular 的惯例,首先需要将 DragDropModule 引入到 app.module.ts 的 imports 数组中,以便在整个应用中启用拖放功能。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule , RoutingComponent} from './app-routing.module';
import { AppComponent } from './app.component';
import { NewCmpComponent } from './new-cmp/new-cmp.component';
import { ChangeTextDirective } from './change-text.directive';
import { SqrtPipe } from './app.sqrt';
import { MyserviceService } from './myservice.service';
import { HttpClientModule } from '@angular/common/http';
import { ScrollDispatchModule } from '@angular/cdk/scrolling';
import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({
declarations: [
SqrtPipe,
AppComponent,
NewCmpComponent,
ChangeTextDirective,
RoutingComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
ScrollDispatchModule,
DragDropModule
],
providers: [MyserviceService],
bootstrap: [AppComponent]
})
export class AppModule { }
注意,DragDropModule 需要从 @angular/cdk/drag-drop 路径导入,并且必须正确添加到 imports 数组中,这是使用拖放功能的前提。
准备数据源:myservice.service.ts
接下来,我们需要准备一个数据源。这里使用现成的服务,通过 HTTP 请求从 JSONPlaceholder 获取用户数据,模拟真实项目中的动态数据加载。
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class MyserviceService {
private finaldata=[];
private apiurl="https://jsonplaceholder.typicode.com/users";
constructor(private https: HttpClient) { }
getData() {
return this.http.get(this.apiurl);
}
}
在组件中调用服务并获取数据
随后在 AppComponent 中注入该服务,并通过订阅获取到的数据,将其存储到 personaldetails 变量中,供模板渲染使用。
import { Component } from '@angular/core';
import { MyserviceService } from './myservice.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title="Angular 7 Project!";
public personaldetails=[];
constructor(private myservice: MyserviceService) {}
ngOnInit() {
this.myservice.getData().subscribe((data) => {
this.personaldetails=Array.from(Object.keys(data), k=>data[k]);
console.log(this.personaldetails);
});
}
}
数据已经成功获取,现在可以在模板中简单展示用户列表。
Angular 7 - Drag and Drop Module
.divlayout{ width: 40%; background-color: #ccc; margin-bottom: 5px; padding: 10px 10px; border: 3px solid #73AD21; }
浏览器中看到的初始界面如下:

在模板中添加 CDK 拖放指令
仅有静态列表是不够的,我们需要在 app.component.html 中添加 Angular CDK 提供的拖放指令,让元素真正可拖拽。修改后的模板代码如下:
Angular 7 - Drag and Drop Module
{{item.name}}
关键属性说明:cdkDropList 定义可放置区域,cdkDropListData 绑定数据源数组,cdkDrag 让每个元素可拖拽,cdkDropListDropped 监听放下事件。现在可以尝试拖动,但会发现松开鼠标后元素会弹回原位——因为我们尚未实现真正的放置逻辑。

为了让拖放生效,需要在组件中编写 onDrop 事件处理函数。首先导入必要的工具函数:
import {CdkDragDrop, moveItemInArray, transferArrayItem}
from '@angular/cdk/drag-drop';
完整的组件代码更新如下:
import { Component } from '@angular/core';
import { MyserviceService } from './myservice.service';
import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title="Angular 7 Project!";
public personaldetails=[];
constructor(private myservice: MyserviceService) {}
ngOnInit() {
this.myservice.getData().subscribe((data) => {
this.personaldetails=Array.from(Object.keys(data),
k=>data[k]);
console.log(this.personaldetails);
});
}
onDrop(event: CdkDragDrop) {
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);
}
}
}
onDrop 函数是核心逻辑:如果拖放发生在同一个列表内,使用 moveItemInArray 调整元素顺序;如果跨列表拖放(本例只有一个列表,但代码已预留接口),则使用 transferArrayItem 移动元素。
再次刷新浏览器,观察最终效果:

现在用户可以自由拖拽列表项,重新排列顺序,整个过程流畅无闪烁。该解决方案完全适用于实际项目中的拖放排序需求。
