Javascript AngularJS 文件拖放指令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14712463/
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
AngularJS file drag and drop in directive
提问by piggyback
This example does pretty much what I would like to port in Angular-js: HTML5 File API.
这个例子几乎完成了我想在 Angular-js 中移植的内容:HTML5 File API。
I have been trying to google some example of directives however I found old example that do massive use of DOM or are not written for Angular 1.0.4.
我一直在尝试搜索一些指令示例,但是我发现旧示例大量使用 DOM 或不是为 Angular 1.0.4 编写的。
Basically this is the pure js code:
基本上这是纯js代码:
var holder = document.getElementById('holder'),
state = document.getElementById('status');
if (typeof window.FileReader === 'undefined') {
state.className = 'fail';
} else {
state.className = 'success';
state.innerHTML = 'File API & FileReader available';
}
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
this.className = '';
e.preventDefault();
var file = e.dataTransfer.files[0],
reader = new FileReader();
reader.onload = function (event) {
console.log(event.target);
holder.style.background = 'url(' + event.target.result + ') no-repeat center';
};
console.log(file);
reader.readAsDataURL(file);
return false;
};
The only possible way I can think of is creating a directive that does
我能想到的唯一可能的方法是创建一个指令
edo.directive('fileDrag', function () {
return {
restrict: 'A',
link: function (scope, elem) {
elem.bind('ondrop', function(e){
e.preventDefault();
var file = e.dataTransfer.files[0], reader = new FileReader();
reader.onload = function (event) {
console.log(event.target);
holder.style.background = 'url(' + event.target.result + ') no-repeat center';
};
console.log(file);
reader.readAsDataURL(file);
return false;
});
}
};
});
However (1) it did not work, (2) before I fix it I would like to know if something exists or if I am doing it properly,
但是(1)它不起作用,(2)在我修复它之前我想知道是否存在某些东西或者我是否做得正确,
Any hint or help is very much appreciated.
非常感谢任何提示或帮助。
回答by Kevin Hakanson
To consolidate the comments into an answer, change ondropto drop, add e.stopPropagation(), change holderto elem.
要将评论合并为答案,请更改ondrop为drop、添加e.stopPropagation()、更改holder为elem。
edo.directive('fileDrag', function () {
return {
restrict: 'A',
link: function (scope, elem) {
elem.bind('drop', function(e){
e.preventDefault();
e..stopPropagation();
var file = e.dataTransfer.files[0], reader = new FileReader();
reader.onload = function (event) {
console.log(event.target);
elem.style.background = 'url(' + event.target.result + ') no-repeat center';
};
console.log(file);
reader.readAsDataURL(file);
return false;
});
}
};
});
I was doing something similar and here is my working solution:
我正在做类似的事情,这是我的工作解决方案:
HTML
HTML
app.directive("dropzone", function() {
return {
restrict : "A",
link: function (scope, elem) {
elem.bind('drop', function(evt) {
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
reader.readAsArrayBuffer(f);
reader.onload = (function(theFile) {
return function(e) {
var newFile = { name : theFile.name,
type : theFile.type,
size : theFile.size,
lastModifiedDate : theFile.lastModifiedDate
}
scope.addfile(newFile);
};
})(f);
}
});
}
}
});
div[dropzone] {
border: 2px dashed #bbb;
border-radius: 5px;
padding: 25px;
text-align: center;
font: 20pt bold;
color: #bbb;
margin-bottom: 20px;
}
<div dropzone>Drop Files Here</div>
回答by Andrew Koval
Preventing default events, and getting file from original event. All can be implemented in directive. You should pass function, for work with files to attribute on-file-drop. Also 'dragging' class is added to dropzone element while dragging. In view it looks like this:
防止默认事件,并从原始事件中获取文件。所有都可以在指令中实现。您应该将函数,用于处理文件以属性 on-file-drop。拖动时还将“拖动”类添加到 dropzone 元素。在视图中它看起来像这样:
<div file-dropzone on-file-drop="myFunction">This is my dropzone </div>
directive:
指示:
function fileDropzoneDirective() {
return {
restrict: 'A',
link: fileDropzoneLink
};
function fileDropzoneLink($scope, element, attrs) {
element.bind('dragover', processDragOverOrEnter);
element.bind('dragenter', processDragOverOrEnter);
element.bind('dragend', endDragOver);
element.bind('dragleave', endDragOver);
element.bind('drop', dropHandler);
function dropHandler(angularEvent) {
var event = angularEvent.originalEvent || angularEvent;
var file = event.dataTransfer.files[0];
event.preventDefault();
$scope.$eval(attrs.onFileDrop)(file);
}
function processDragOverOrEnter(angularEvent) {
var event = angularEvent.originalEvent || angularEvent;
if (event) {
event.preventDefault();
}
event.dataTransfer.effectAllowed = 'copy';
element.addClass('dragging');
return false;
}
function endDragOver() {
element.removeClass('dragging');
}
}
}

