Angular Material CDK Drag&Drop文本区插入值及DragDropModule兼容问题
实现拖拽插入指定内容到文本区光标位置
1. 正常启用DragDropModule
先在app.module.ts的imports数组中取消DragDropModule的注释,该模块和现有逻辑不存在原生冲突,之前出现的异常均为配置问题。
2. 配置拖拽元素与预览
列表项绑定cdkDrag指令,通过cdkDragData传递完整的EntryKeyValue对象,列表仅展示key属性,同时配置*cdkDragPreview显示对应的value:
<div *ngFor="let item of ekvs" cdkDrag [cdkDragData]="item"> {{ item.key }} <div *cdkDragPreview class="drag-preview"> {{ item.value }} </div> </div>
*cdkDragPreview不显示的问题可通过添加基础样式解决:
.drag-preview { padding: 6px 12px; background: #ffffff; border: 1px solid #d1d5db; border-radius: 4px; box-shadow: 0 3px 6px rgba(0,0,0,0.1); }
3. 配置文本区为放置目标
给textarea元素绑定cdkDropList指令,监听放置事件:
<textarea #textElem cdkDropList (cdkDropListDropped)="handleDrop($event, textElem)" rows="8" cols="60" ></textarea>
4. 实现光标位置插入逻辑
在组件中编写放置事件处理方法:
import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { EntryKeyValue } from './你的接口路径'; // ... handleDrop(event: CdkDragDrop<EntryKeyValue>, textarea: HTMLTextAreaElement) { // 取出拖拽传递的value属性 const insertContent = event.item.data.value; // 获取文本区当前光标位置 const start = textarea.selectionStart; const end = textarea.selectionEnd; const originalText = textarea.value; // 拼接新文本,不覆盖原有内容 textarea.value = originalText.slice(0, start) + insertContent + originalText.slice(end); // 把光标移动到插入内容的末尾 textarea.selectionStart = textarea.selectionEnd = start + insertContent.length; // 触发input事件保证双向绑定同步更新 textarea.dispatchEvent(new Event('input')); }
兼容说明
你之前的逻辑异常是因为同时使用了原生拖拽API和CDK拖拽API导致事件冲突,统一使用CDK提供的拖拽相关API即可完全解决该问题,不需要保留原生的drag、drop相关事件监听。
内容的提问来源于stack exchange,提问作者user1410223
相关产品推荐
相关产品推荐

