我有一个<div>
元素,其中指令dragAndDrop
设置为属性:
<div ng-class="divClass" drag-and-drop>Drop files here</div>
(作为一方,不太重要的说明,ng-class的行为不符合预期,但那是separate issue)
我想要的是用户将文件从桌面拖放到div。在这样做的时候,我使用angular.bind()
来检测丢弃事件。当然,一旦他们放弃,我就会调用e.stopPropagation()
和e.preventDefault()
,但页面会继续,无论如何重定向页面。我做错了什么会妨碍上述两种方法的执行?
dragAndDrop
指令:
directive('dragAndDrop', function() {
return {
restrict: 'A',
link: function($scope, elem, attr) {
elem.bind('dragenter', function(e) {
e.stopPropagation();
e.preventDefault();
// still can't get this one to behave:
// https://stackoverflow.com/q/15419839/740318
$scope.divClass = 'on-drag-enter';
});
elem.bind('dragleave', function(e) {
e.stopPropagation();
e.preventDefault();
$scope.divClass = '';
});
elem.bind('drop', function(e) {
var droppedFiles = e.dataTransfer.files;
// It's as though the following two methods never occur
e.stopPropagation();
e.preventDefault();
if (droppedFiles.length > 0) {
for (var i=0,ii=droppedFiles.length;i<ii;i++) {
$scope.files.push(droppedFiles[i]);
}
}
});
}
};
});
答案 0 :(得分:11)
Angular不知道您注册的事件处理程序何时被触发,因此您需要通知Angular您已更改范围变量。您可以使用$apply
函数执行此操作。
$scope.$apply(function () {
$scope.divClass = 'on-drag-enter';
});
当涉及到drop处理程序时,你是正确的 - var droppedFiles = e.dataTransfer.files;
之后的语句永远不会运行,因为语句导致了运行时错误。
e
是一个jQuery事件,而dataTransfer
是实际DOM事件的属性。要解决此问题,您需要通过originalEvent
属性访问原始事件。
var droppedFiles = e.originalEvent.dataTransfer.files;
<强>更新强>
e.originalEvent
只有在角度之前包含jQuery时才需要,但由于你没有在你的plnkr中做到这一点,该解决方案无效,我为此道歉。
似乎你需要选择preventDefault
of the dragover event的支持(也许这可以在其他事件中完成 - 没有经过测试。)
elem.bind('dragover', function (e) {
e.stopPropagation();
e.preventDefault();
});