Angular动态配置[cdkDropListConnectedTo]实现指定规则拖拽
Angular CDK拖拽容器连接配置方案
要满足你提出的拖拽规则,同时避免冗余代码,可以通过组件类收集容器引用+动态生成连接列表的方式实现,具体步骤如下:
1. 在组件类中收集所有拖拽容器引用
首先用@ViewChildren获取所有通过模板变量#ref标记的cdkDropList实例,再写一个方法根据当前容器索引返回对应的可连接列表:
import { Component, ViewChildren, QueryList } from '@angular/core'; import { CdkDropList } from '@angular/cdk/drag-drop'; @Component({ selector: 'your-component-selector', templateUrl: './your-component.component.html' }) export class YourComponent { @ViewChildren('ref') dropLists!: QueryList<CdkDropList>; books = [/* 你的书籍容器数据 */]; // 根据当前容器索引返回可连接的容器列表 getConnectedLists(index: number): CdkDropList[] { // 容器1(对应索引0)可连接到容器2、3、4(索引1-3) // 容器2-4可互相连接,同样是排除容器1后的所有容器 return this.dropLists.filter((_, listIndex) => listIndex !== 0); } drop(event: any) { // 额外判断:禁止将其他容器的项目拖入容器1 if (event.container.id === 'book-container-0') { // 把拖拽项放回原容器,终止操作 event.previousContainer.data.push(event.item.data); return; } // 正常处理拖拽逻辑(比如移动数据、更新视图等) // ... } }
2. 修改模板中的连接配置
把[cdkDropListConnectedTo]绑定到上面的getConnectedLists方法,传入当前循环的索引:
<div *ngFor="let book of books; let i = index"> <div> <div cdkDropList id="book-container-{{i}}" #ref="cdkDropList" [cdkDropListData]="book.getDropListData()" [cdkDropListConnectedTo]="getConnectedLists(i)" (cdkDropListDropped)="drop($event)"> <div> <p class="headline">{{book.getHeadline()}}</p> <!-- 注意:拖拽项需要加上cdkDrag指令 --> <div *ngFor="let item of book.getDropListData()" cdkDrag> {{item}} </div> </div> </div> </div> </div>
方案说明
- 用
QueryList统一管理所有拖拽容器,避免手动逐个配置连接目标,减少冗余代码; getConnectedLists方法通过索引区分容器类型,一次性满足三个规则的连接需求;- 额外在
drop事件中拦截向容器1的拖拽操作,因为cdkDropListConnectedTo只控制可拖拽的目标显示,无法完全禁止拖入,需要逻辑层面补充判断。
内容的提问来源于stack exchange,提问作者coder
相关产品推荐
相关产品推荐

