Angular 12 Material CDK拖拽实现元素替换占位符功能咨询
调整步骤如下
1. 先修正HTML代码的两处问题
你当前给列表B(占位符列表)的拖拽属性配置有误,且需要禁止占位符被拖拽、禁止列表B内部排序,修改后代码如下:
<mat-drawer-container class="example-container"> <mat-drawer class="sideMenu" mode="side" role="dragAndDrop" position="end" opened> <div class="sideNav-container"> <!-- 列表A:可选拖拽源 --> <div cdkDropList #moviesList="cdkDropList" [cdkDropListData]="MoviesList" [cdkDropListConnectedTo]="[doneMovieList]" class="drag-list-sidenav" (cdkDropListDropped)="onDrop($event)" > <div class="movie-block" *ngFor="let movie of MoviesList" cdkDrag> <span mat-raised-button matTooltip="bla" matTooltipPosition="left" class="" >{{movie}}</span> </div> </div> </div> </mat-drawer> <mat-drawer-content class="sideMainContent"> <div class="container"> <!-- 列表B:占位符目标列表 --> <div cdkDropList #doneMovieList="cdkDropList" [cdkDropListData]="MoviesWatched" cdkDropListSortingDisabled="true" class="movie-list" (cdkDropListDropped)="onDrop($event)" > <!-- 加cdkDragDisabled禁止占位符被拖拽 --> <div class="movie-block" *ngFor="let watched of MoviesWatched" cdkDrag cdkDragDisabled>{{watched}}</div> </div> </div> </mat-drawer-content> </mat-drawer-container>
2. 修改TS的onDrop逻辑
把默认的transferArrayItem插入逻辑换成替换逻辑,修改后代码如下:
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; export class ListComponent{ MoviesList: string[] = [ 'The Far Side of the World', 'Morituri', 'Napoleon Dynamite', 'Pulp Fiction', 'Blade Runner', 'Cool Hand Luke', 'Heat', 'Juice' ]; MoviesWatched: string[] = [ 'shouled be Placeholde1', 'shouled be Placeholde2', ]; constructor(){} onDrop(event: CdkDragDrop<string[]>) { // 同容器拖拽:保留A内部排序逻辑,不需要可以删掉 if (event.previousContainer === event.container) { moveItemInArray(event.container.data, event.previousIndex, event.currentIndex); } else { // 跨容器拖拽:执行替换逻辑 // 1. 取出被拖拽的元素 const draggedItem = event.previousContainer.data[event.previousIndex]; // 2. 从原列表A删除对应元素 event.previousContainer.data.splice(event.previousIndex, 1); // 3. 替换列表B对应位置的占位符 event.container.data[event.currentIndex] = draggedItem; } } }
逻辑说明
- 给列表B加了
cdkDropListSortingDisabled="true"禁止内部元素排序,避免占位符顺序被打乱 - 给列表B的每一项加了
cdkDragDisabled禁止占位符被拖拽到其他列表 - 跨容器拖拽时不再调用默认的
transferArrayItem(该方法会给目标数组新增元素),而是直接替换目标数组对应索引的值,完全符合你要的替换占位符的需求 - 如果你不需要列表A内部拖拽排序,可以直接删除同容器判断里的
moveItemInArray逻辑
内容的提问来源于stack exchange,提问作者Der_V
相关产品推荐
相关产品推荐

