如何从 Angular 2 onDrop 事件中获取文件?
Posted
技术标签:
【中文标题】如何从 Angular 2 onDrop 事件中获取文件?【英文标题】:How to get files from angular 2 onDrop event? 【发布时间】:2017-08-16 16:02:32 【问题描述】:我试过这样,但onDrop
方法在我放到它时不返回图像文件...
onDragStart(event, data: any)
event.dataTransfer.setData('data', data);
onDrop(event, data: any)
let dataTransfer = event.dataTransfer.getData('data');
event.preventDefault();
allowDrop(event)
event.preventDefault();
<div (drop)="onDrop($event, dropData)" (dragover)="allowDrop($event)"></div>
<div (dragstart)="onDragStart($event, dragData)"></div>
有什么解决办法吗?
【问题讨论】:
为什么要阻止事件的默认行为? 如果不阻止,拖放将不起作用... 【参考方案1】:onDrop 事件仅在 onDragOver 有 preventDefault()
和 stopPropagation()
方法在事件上运行时触发。
HTML
<div
(drop)="onDrop($event)"
(dragover)="onDragOver($event)"
>
Drop target
</div>
DropComponent.ts
export class DropComponent
onDrop(event)
event.preventDefault();
onDragOver(event)
event.stopPropagation();
event.preventDefault();
更新
这是必需的,因为默认情况下,浏览器会在拖放到 html 元素时阻止任何事情发生。更多信息请访问 MDN - Defining a valid drop zone
【讨论】:
如果你能解释为什么会这样就太好了。【参考方案2】:下面是 Angular 2/4/6 中拖放的完整代码:
drag.component.ts:
import Component from '@angular/core';
@Component(
selector: 'drag-root',
templateUrl: './drag.component.html',
styleUrls: ['./drag.component.css']
)
export class AppComponent
allowDrop(ev)
ev.preventDefault();
drag(ev)
ev.dataTransfer.setData("text", ev.target.id);
drop(ev)
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
拖动.component.html:
<h2>Drag and Drop</h2>
<div id="div1"
(drop)="drop($event)"
(dragover)="allowDrop($event)">
<img
src="https://images.pexels.com/photos/658687/pexels-photo-658687.jpeg?auto=compress&cs=tinysrgb&h=350"
draggable="true"
(dragstart)="drag($event)"
id="drag1"
>
</div>
<div id="div2"
(drop)="drop($event)"
(dragover)="allowDrop($event)">
</div>
drag.component.css:
#div1, #div2
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
快照:
【讨论】:
它对我有用,但为了从 div 获取数据,我使用了下面的代码,它给出了文件 Object, var data = event.dataTransfer.files[0];【参考方案3】:您可以将 onDrop 功能包装到可重用指令中。像这样:
https://gist.github.com/darrenmothersele/7afda13d858a156ce571510dd78b7624
将此指令应用于元素:
<div (appDropZone)="onDrop($event)"></div>
该事件由已删除文件的 javascript 数组触发。因此,您在组件中的 onDrop
实现如下所示:
onDrop(files: FileList)
console.log( files );
【讨论】:
【参考方案4】:正如其他人所说,您需要在 (dragover)
事件上调用 event.preventDefault()
和 event.stopPropagation()
以使您的容器成为有效的放置区。
我编写了一个高度可定制的 Angular 组件,它实现了正确的 Drag'n'Drop 行为,因此我不需要一遍又一遍地复制它,它会返回一个已删除文件的列表作为输出事件。 这可以找到here。
导入模块后,您可以访问组件:
<ngx-dropzone [multiple]="false" [maxFileSize]="2000"></ngx-dropzone>
您可以设置一些选项,它带有一个不错的默认样式(可以在 GitHub 存储库中找到屏幕截图)。如果您愿意,您甚至可以使用您自己的 div
容器和您的自定义样式和悬停效果,并将其放入 dropzone。可以在 API 描述中找到这方面的详细信息。
<ngx-dropzone [customContent]="customDropzone" (filesAdded)="onFilesDropped($event)">
<ng-template #customDropzone>
<div class="custom-dropzone">
This is my custom content
</div>
</ng-template>
【讨论】:
我为此花了一整天的时间,但您的组件在 3 分钟内完成。我有一个问题,我们可以在同一个保管箱中显示上传的图像吗? @KishanOza 目前尚未实现,但我在 GitHub 上也收到了很多请求。我将尝试在接下来的几周内添加图像预览。我建议您“观看”存储库,以便了解更新。 是的,我设法通过在数组中添加图像并分别显示它们来做到这一点。但如果我们可以在 self @PeterFreeman 的下拉框中显示相同的图像,那就太好了 现在可以使用最新版本。 :) 是的,这很酷..但它一次只显示一个图像..如果我删除新图像,它将覆盖前一个图像:(任何解决方案?并且没有删除该图像的选项:( 我正在创建类似 playstore 和 appstore 上传的 UI,用户可以在其中添加屏幕截图【参考方案5】:您可以尝试使用Hostlistener
装饰器进行拖动事件,您可以看到它已实现,例如here in ng2-file-upload
【讨论】:
Hostlistener
将如何提供帮助?
我尝试添加@HostListener('drop', ['$event'])
,但它仍然返回空事件...【参考方案6】:
一个非常简单的指令,允许您将文件放置在任何位置。
IE:
@Directive(
selector: '[dropFileZone]'
)
export class DropFileZoneDirective
@Output() onDropFile = new EventEmitter<File>();
constructor()
@HostListener('dragover', ['$event'])
allowDrop(event)
event.stopPropagation();
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
@HostListener('drop', ['$event'])
async onDrop(event)
event.stopPropagation();
event.preventDefault();
let fileList = event.dataTransfer.files; // Array of all files
const fileExists: boolean = fileList.length > 0;
if (!fileExists)
return;
this.onDropFile.emit(fileList[0]);
在 .html 文件上使用它的方式:
<div dropFileZone (onDropFile)="handleDroppedFile($event)"> </div>
【讨论】:
以上是关于如何从 Angular 2 onDrop 事件中获取文件?的主要内容,如果未能解决你的问题,请参考以下文章