HTML 5 拖放与 Angular 4
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47975237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HTML 5 Drag & Drop with Angular 4
提问by Sumchans
I am trying to get the native HTML 5 drag & drop working in my angular app. I got the drag, fire the drag & the dragOver events, but the drop unfortunately doesn't fire anything. Here I have the HTML and drag events code below.
我正在尝试让原生 HTML 5 拖放在我的 angular 应用程序中工作。我得到了拖动,触发了拖动和 dragOver 事件,但不幸的是,下降没有触发任何东西。在这里,我有下面的 HTML 和拖动事件代码。
<ul *ngFor="let channel of channelList" >
<li class="list-group-item" *ngIf="channel.channel.substr(0, 1) === head"
style="float:left; margin:0.5px" draggable="true" (dragstart)="drag(channel)">
<ng-container *ngIf="channel.compChannel.compChannelLogo.length !== 0; else noCompChannel">
<img class="img-rounded" src="{{ channel.logo }}" alt="{{ channel.channel }}" width="100" height="100">
<img class="img-rounded" src="{{ channel.compChannel.compChannelLogo }}" alt="{{ channel.channel.compChannelName }}" width="100" height="100">
</ng-container>
<ng-template #noCompChannel>
<img class="img-rounded" src="{{ channel.logo }}" alt="{{ channel.channel }}"
width="100" height="100" >
</ng-template>
</li>
</ul>
<ul class="list-group" *ngFor="let channels of currentPickSelection" dropzone="copy">
<li class="list-group-item" style="float:Left; margin-left:0.5px" (dragover)="dragOver(channels[0])" (dragend)="drop(event)">
<ng-container *ngIf="channels[0].compChannel.compChannelLogo.length !== 0; else noCompChannel">
<img class="img-rounded" src="{{ channels[0].logo }}" alt="{{ channels[0].channel }}" width="70" height="70">
<img class="img-rounded" src="{{ channels[0].compChannel.compChannelLogo }}" alt="{{ channels[0].compChannel.compChannelName }}"
width="70" height="70">
</ng-container>
<ng-template #noCompChannel>
<img class="img-rounded" src="{{ channels[0].logo }}" alt="{{ channels[0].channel }}" width="70" height="70">
</ng-template>
<br>
<strong>
<font size="2">{{ channels[0].pickCode }}</font>
</strong>
</li>
</ul>
drag(channel) {
console.log(channel);
}
dragOver(channel) {
this.draggedChannel = channel;
// console.log(this.draggedChannel);
}
drop(e) {
console.log(e);
}
回答by Shubham Verma
I made it without any other module in Angular 2/4/5/6, You can also make it by using below code:
我在 Angular 2/4/5/6 中没有任何其他模块的情况下制作了它,您也可以使用以下代码制作它:
drag.component.html:
drag.component.html:
<h2>Drag and Drop demo</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>
drag.component.ts:
拖动组件.ts:
import { Component } from '@angular/core';
@Component({
selector: 'drag-root',
templateUrl: './drag.component.html',
styleUrls: ['./drag.component.css']
})
export class AppComponent {
drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
allowDrop(ev) {
ev.preventDefault();
}
drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
}
drag.component.css:
拖动组件.css:
#div1, #div2 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
回答by Phani Kumar
<div (dragover)="onDragOver($event)"
(dragleave)="onDragLeave($event)" (drop)="onDrop($event)">
</div>
In your Component:
在您的组件中:
onDrop(event: any) {
event.preventDefault();
event.stopPropagation();
// your code goes here after droping files or any
}
onDragOver(evt) {
evt.preventDefault();
evt.stopPropagation();
}
onDragLeave(evt) {
evt.preventDefault();
evt.stopPropagation();
}
回答by Emerica
Here is a solution on Angular 7:
这是Angular 7的解决方案:
Material(https://material.angular.io/) explains it perfectly (you have to take version >= 7.1). Here is a link to API.
Material( https://material.angular.io/) 完美地解释了它(你必须使用版本 >= 7.1)。这是API的链接。
First, import "DragAndDrop" module in your modules:
首先,在您的模块中导入“DragAndDrop”模块:
import {DragDropModule} from '@angular/cdk/drag-drop';
Then you just have to add "cdkDrag" directive to your HTML element:
然后你只需要将“cdkDrag”指令添加到你的 HTML 元素中:
<div class="example-box" cdkDrag>
Drag me around
</div>
Stackblitz (from material): here
Stackblitz(来自材料): 这里
It's really easy to use and there are interesting options if you need to do a more specific drag and drop (for example with a position locking) !
它非常易于使用,如果您需要进行更具体的拖放(例如使用位置锁定),还有一些有趣的选项!
回答by WasiF
Simple but most powerful package
简单但最强大的包
supports angular version >= 4.x
支持角度版本 >= 4.x
for documentation
用于文档
for demo
用于演示
How to use it?
如何使用它?
Install
安装
// if you use npm
npm install angular2-draggable
// or if you use yarn
yarn add angular2-draggable
Import
进口
import { AngularDraggableModule } from 'angular2-draggable';
@NgModule({
imports: [
...,
AngularDraggableModule
],
})
export class AppModule { }
and finally use
最后使用
// Basic Usage
<div ngDraggable>Drag Me!</div>
回答by Rsona
To use drag and drop in angular 4 application you can use npm module "ngx-uploader".
要在 angular 4 应用程序中使用拖放,您可以使用 npm 模块“ngx-uploader”。
You will find the integration step from below link:
您可以从以下链接找到集成步骤:
https://www.npmjs.com/package/ngx-uploader
https://www.npmjs.com/package/ngx-uploader
All the imports parameter and classes you can take from the above link.
您可以从上述链接中获取的所有导入参数和类。
Here is my code for angular:
这是我的角度代码:
if (output.type === 'allAddedToQueue') { // when all files added in queue
// uncomment this if you want to auto upload files when added
const event: UploadInput = {
type: 'uploadAll',
url: API_BASE +'/api/uploads',
method: 'POST',
data:{total_files: this.files.length.toString()}
};
this.uploadInput.emit(event);
} else if (output.type === 'addedToQueue' && typeof output.file !== 'undefined') { // add file to array when added
this.files.push(output.file);
} else if (output.type === 'uploading' && typeof output.file !== 'undefined') {
// update current data in files array for uploading file
const index = this.files.findIndex(file => typeof output.file !== 'undefined' && file.id === output.file.id);
this.files[index] = output.file;
} else if (output.type === 'removed') {
// remove file from array when removed
this.files = this.files.filter((file: UploadFile) => file !== output.file);
} else if (output.type === 'dragOver') {
this.dragOver = true;
} else if (output.type === 'dragOut') {
this.dragOver = false;
} else if (output.type === 'drop') {
this.dragOver = false;
}else if (output.type === 'done') {
if (output.file.response.status == 200) {
var uploaded_files = output.file.response.data;
this.propertyImage.push(uploaded_files);
}
else {
this.msgs = [];
this.msgs.push({ severity: 'error', summary: 'Error Message', detail: 'unable to upload images' });
}
In the above code for output === done, you will get response from server side (In my case nodejs)
在上面输出 === done 的代码中,你会得到服务器端的响应(在我的例子中是 nodejs)
Below you can find the code for backend:
您可以在下面找到后端的代码:
var formidable = require('formidable'),
http = require('http'),
util = require('util');
var form = new formidable.IncomingForm();
var src = './public/images/properties';
var dst_small = './public/images/properties/small'
var dst_medium = './public/images/properties/medium'
var validImage = false;
form.keepExtensions = true; //keep file extension
form.uploadDir = src;
form.onPart = function (part) {
if (!part.filename || part.filename.match(/\.(jpg|jpeg|png)$/i)) {
validImage = true;
this.handlePart(part);
}
else {
validImage = false;
return res.json({ status: 404, msg: part.filename + ' is not allowed.' });
}
}
form.parse(req, function (err, fields, files) {
if (validImage) {
var image = files.file.path.split("/")[3];
var name = files.file.path.split("/")[3];
easyimg.rescrop({
src: files.file.path, dst: dst_small + '/' + files.file.path.split('/')[3],
width: 100, height: 100,
cropwidth: 100, cropheight: 100,
x: 0, y: 0
}).then(
function (image) {
// console.log('Resized and cropped: ' + image.width + ' x ' + image.height);
},
function (err) {
// console.log(err);
}
);
// for largeImage
easyimg.rescrop({
src: files.file.path, dst: dst_medium + '/' + files.file.path.split('/')[3],
width: 300, height: 300,
cropwidth: 300, cropheight: 300,
x: 0, y: 0
}).then(
function (image) {
// console.log('Resized and cropped: ' + image.width + ' x ' + image.height);
return res.json({ status: 200, msg: 'Uploaded images', data: image });
},
function (err) {
console.log(err);
}
);
} else {
return res.json({ status: 500, msg: constant.message.error_profile_pic_type });
}
});
Please change your image path according to your file path. I have used this code and it worked for me.
请根据您的文件路径更改您的图像路径。我已经使用了这段代码,它对我有用。
Hope the above code will help for you.
希望上面的代码对你有帮助。
Thanks !!
谢谢 !!
回答by Sumchans
This is this the way I got it working. preventDefault() functions throws error, changed it for return false which worked fine. Thanks guys for the prompt responses.
这就是我让它工作的方式。preventDefault() 函数抛出错误,将其更改为返回 false 效果很好。谢谢大家的及时回复。
drag(channel) {
console.log(channel);
}
onDragOver(channel: any) {
console.log("Drag Over");
return false;
}
onDrop(e:any) {
console.log("Drop");
}
回答by sachin
Use dropevent. This will fire only when you drop a file.
使用放置事件。这只会在您删除文件时触发。