Javascript 如何从angular 2 onDrop事件获取文件?

Javascript 如何从angular 2 onDrop事件获取文件?,javascript,angular,drag-and-drop,image-upload,Javascript,Angular,Drag And Drop,Image Upload,我试过这样做,但是当我放下它时,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.

我试过这样做,但是当我放下它时,
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();
}


有什么解决方案吗?

您可以尝试对拖动事件使用
Hostlistener
装饰器,您可以看到它的实现,例如只有当onDragOver在事件上运行
preventDefault()
StopRopAgation()
方法时,onDrop事件才会触发

HTML

<div
    (drop)="onDrop($event)"
    (dragover)="onDragOver($event)"
>
    Drop target
</div>
更新

这是必需的,因为默认情况下,浏览器会阻止在拖放到HTML元素时发生任何事情。更多信息请访问
以下是在Angular 2/4/6中拖放的完整代码:

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));
  }
}
<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"
      width="88" 
      height="31">
</div>

<div id="div2" 
  (drop)="drop($event)" 
  (dragover)="allowDrop($event)">
</div>
#div1, #div2 {
    float: left;
    width: 100px;
    height: 35px;
    margin: 10px;
    padding: 10px;
    border: 1px solid black;
}
拖动.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));
  }
}
<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"
      width="88" 
      height="31">
</div>

<div id="div2" 
  (drop)="drop($event)" 
  (dragover)="allowDrop($event)">
</div>
#div1, #div2 {
    float: left;
    width: 100px;
    height: 35px;
    margin: 10px;
    padding: 10px;
    border: 1px solid black;
}
drag.component.html:

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));
  }
}
<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"
      width="88" 
      height="31">
</div>

<div id="div2" 
  (drop)="drop($event)" 
  (dragover)="allowDrop($event)">
</div>
#div1, #div2 {
    float: left;
    width: 100px;
    height: 35px;
    margin: 10px;
    padding: 10px;
    border: 1px solid black;
}
快照:

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));
  }
}
<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"
      width="88" 
      height="31">
</div>

<div id="div2" 
  (drop)="drop($event)" 
  (dragover)="allowDrop($event)">
</div>
#div1, #div2 {
    float: left;
    width: 100px;
    height: 35px;
    margin: 10px;
    padding: 10px;
    border: 1px solid black;
}


您可以将onDrop功能包装到可重用指令中。像这样:

将此指令应用于元素:

<div (appDropZone)="onDrop($event)"></div>

正如其他人所说,您需要在
(dragover)
事件上调用
事件.preventDefault()
事件.stopPropagation()
,使容器成为有效的dropzone

我已经编写了一个高度可定制的Angular组件,它实现了正确的拖放行为,因此我不需要反复复制它,它会将拖放的文件列表作为输出事件返回。
这是可以找到的

导入模块后,您可以访问组件:

<ngx-dropzone [multiple]="false" [maxFileSize]="2000"></ngx-dropzone>

为什么要阻止事件的默认行为?如果不阻止,拖放操作将不起作用。
Hostlistener
有何帮助?我试图添加
@Hostlistener('drop',['$event']))
但它仍然返回空事件…如果您能解释为什么会这样,那就太好了。我为此花了一整天的时间,但您的组件在3分钟内完成。。我有一个问题,我们可以在同一个dropbox中显示上传的图像吗?@KishanOza这目前还没有实现,但我在GitHub上也收到了很多请求。在接下来的几周里,我将尝试添加图像预览。我建议您“观看”回购协议,以便了解更新情况。是的,我已设法通过在阵列中添加图像并单独显示来做到这一点。但是,如果我们能在self@PeterFreemanIt的下拉框中显示相同的图像,那就太好了。现在,最新版本的self@PeterFreemanIt已成为可能。:)是的,很酷。。但它一次只能显示一张图像。。如果我删除新的图像,它将覆盖上一个图像:(任何解决方案?并且没有删除该图像的选项:(我正在创建用户界面,如playstore和appstore upload,用户可以在其中添加屏幕快照)这对我来说很有效,但为了从div获取数据,我使用了下面的代码,它给出了文件对象var data=event.dataTransfer.files[0];