Angular Material、cdk、拖放、拖放和插入到 TextArea 字段的当前位置
Posted
技术标签:
【中文标题】Angular Material、cdk、拖放、拖放和插入到 TextArea 字段的当前位置【英文标题】:Angular Material,cdk, Drag & Drop, dropping,and inserting into current position of TextArea Field 【发布时间】:2021-12-06 18:59:17 【问题描述】:我正在检查这些示例:
https://jsfiddle.net/qskxzh0e/3/http://jsfiddle.net/3p1nra6m/1/ 和https://stackblitz.com/edit/angular-component-drag
https://material.angular.io/cdk/drag-drop/overview
可以插入(不替换所有包含的文本)一些 Token 表单列表为 cdkDropListDropped
或 cdkDrag
?
我已经解决了我之前的问题,因为我可以插入 Textarea,并且我有新的挑战,这里是我的 stackblitz 代码(抱歉颜色和闪烁,因为我正在测试方法 ):
对于这段代码,我实现了一个接口:
export interface EntryKeyValue
key: string;
value: string;
在我的组件中,我有一个类似的数组:
ekvs: EntryKeyValue[] = [
key: 'first',
value: 'First Item'
,
key: 'second',
value: 'Second Item'
,
key: 'third',
value: 'Third Item'
,
];
我想在我的 html 中显示 key
属性,但在我的 Textarea 中我想插入 value
属性。
例如:我应该显示 'third',但我应该在我的 textarea 中插入 'Third Item'。
怎么做?
在我的app.module.ts
文件的imports
数组中,我评论了//, DragDropModule
,因为*cdkDragPreview
没有显示!为了让用户知道插入的最终值是什么。但是我的方法不能像右下角显示的那样工作!!!
DragDropModule
是否与我的方法兼容?以及如何同时使用这两种方法?
【问题讨论】:
stackblitz.com/edit/angular-yhfiqn?file=app%2Fapp.component.ts jsfiddle.net/3p1nra6m/1 github.com/angular/components/issues/9979 stackblitz.com/angular/… 查看此答案***.com/a/27990218/1410223 和此帖子:kryogenix.org/code/browser/custom-drag-image.html 【参考方案1】:使用textarea
时,最好使用HTML5 Drag and Drop API,这正是您在演示中使用的。
使用 Angular CDK 拖放,您必须自己检测插入光标在 textarea 中的位置。
如果您想显示一个值但插入另一个值,您需要将所需的值传递给DataTransfer.setData() 方法。
只需在拖动元素上添加一些属性
<div
class="example-box"
...
[attr.data-drag-data]="ekv.value"
现在您可以从 ts 代码中读取该值
event.dataTransfer.setData('text/plain', event.target.dataset.dragData);
Forked Stackblitz
更新
为了自定义 HTML5 d&d 预览,您可以使用DataTransfet.setDragImage() 方法
public dragstart_handler(event: any)
const preview = event.target.cloneNode(true);
// store it for element so that we can remove it from DOM later on
event.target.preview = preview;
preview.className = 'preview';
preview.style.cssText = `position: absolute; top: -100%; left: -100%;
width: $event.target.offsetWidthpx; `;
document.body.appendChild(preview);
event.dataTransfer.setDragImage(preview, 0, 0);
...
public dragend_handler(event: any)
event.target.preview.parentNode.removeChild(event.target.preview);
Updated Stackblitz
【讨论】:
感谢您的帮助。但是,我怀疑如何启用 Preview HTML5 Drag And Drop 替换*cdkDragPreview
?
@Anita 我扩展了我的答案
preview
在event.target.preview
中使用时是任意属性吗?根据文档,它不是属性。
@Anita 是的,这只是我的自定义任意属性。我使用它来存储对该属性将获取并从 DOM 中删除的元素的引用【参考方案2】:
查看这篇文章: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-* 为了添加您的自定义属性并在您的 Modal 组件中使用它们。
在您的 HTML 模板中添加:[attr.data-value]="ekv.value"
在带有drabggable="true"
的 div 内
<div
class="example-box"
draggable="true"
(drag)="drag_handler($event)"
(dragend)="dragend_handler($event)"
(dragenter)="dragenter_handler($event)"
(dragleave)="dragleave_handler($event)"
(dragover)="dragover_handler($event)"
(dragstart)="dragstart_handler($event)"
(drop)="drop_handler($event)"
[attr.data-value]="ekv.value"
*ngFor="let ekv of ekvs" cdkDrag
>
<div>
<p *cdkDragPreview><span class="blink preview">ekv.value</span></p>
</div>
<div class="example-custom-placeholder" *cdkDragPlaceholder></div>
ekv.key
</div>
为了添加预览,我以更改样式为例:
在您的 Modal 组件中,将您的 dragstart_handler method
编辑为:
public dragstart_handler(event: any)
const crt = event.target.cloneNode(true);
crt.style.backgroundColor = "#D1F8D1";
crt.style.color = "darkred";
crt.style.position = "absolute";
crt.style.borderWidth = "initial";
crt.style.borderStyle = "dashed";
crt.style.borderColor = "blue";
crt.style.top = "-1000px";
crt.className += " blink";
crt.style.right = "0px";
crt.innerText = event.target.dataset.value;
document.body.appendChild(crt);
event.dataTransfer.setDragImage(crt, 0, 0);
//event.dataTransfer.setData('text/plain', event.target.innerText);
event.dataTransfer.setData('text/plain', event.target.dataset.value);
document.getElementById("paragraph2").innerHTML = "Paragraph2: Starting dragging the <span style='color:red'>" + event.target.innerText + "</span> element.";
也请查看此帖子:https://web.dev/drag-and-drop/
【讨论】:
以上是关于Angular Material、cdk、拖放、拖放和插入到 TextArea 字段的当前位置的主要内容,如果未能解决你的问题,请参考以下文章
Angular Material、cdk、拖放、拖放和插入到 TextArea 字段的当前位置
Angular 嵌套拖放 / CDK 材质 cdkDropListGroup cdkDropList nested