Angular js / MVC中的文件拖放功能不起作用 [英] File drag and drop functionality in Angular js/MVC not working

查看:85
本文介绍了Angular js / MVC中的文件拖放功能不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Angular js / MVC中实现简单的文件拖放功能。



我为拖放创建了指令。



 (function(angular,undefined){'use strict'; angular.module('fileupload ',[]).directive( myDirective,函数($ parse){返回{限制:'A',链接:fileDropzoneLink};函数fileDropzoneLink(scope,element,attrs){element.bind('dragover',processDragOverOrEnter ); element.bind('dragenter',processDragOverOrEnter); element.bind('dragend',endDragOver); element.bind('dragleave',endDragOver); element.bind('drop',dropHandler); var onImageDrop = $ parse(attrs.onImageDrop); //当文件是dr opped var loadFile =函数(文件){scope.uploadedFiles =文件; scope。$ apply(onImageDrop(scope)); };函数dropHandler(angularEvent){var event = angularEvent.originalEvent || angularEvent; var files = event.dataTransfer.files; event.preventDefault(); loadFile(files)}函数processDragOverOrEnter(angularEvent){var event = angularEvent.originalEvent || angularEvent; if(event){event.preventDefault(); } event.dataTransfer.effectAllowed =‘复制’; element.addClass('dragging');返回false; }函数endDragOver(){element.removeClass(‘dragging’); }}});}(角));  



这是模板



 < div class = dropzone data-my-Directive on-image-drop = $ ctrl.fileDropped()>在此处拖放pdf文件< / div>  



这是我的组件代码



 (function(angle,undefined){'use strict'; angular.module('test',[]).component('contactUs',contactUs( ));函数contactUs(){ContactUs。$ inject = ['$ scope','$ http'];函数ContactUs($ scope,$ http){var ctrl = this; ctrl.files = []; ctrl.services = {$ scope:$ scope,$ http:$ http,}; } //文件已删除ContactUs.prototype.fileDropped = function(){var ctrl = this; var files = ctrl.services。$ scope.uploadedFiles; angular.forEach(文件,函数(文件,键){ctrl.files.push(file);}); } return {controller:ContactUs,templateUrl:‘partials / home / contactus /’}; }}(角度));  



有时拖放有效绝对没问题。但是有时我遇到以下问题,并且拖放操作不起作用,并且得到了无效的黑色光标。



,我也看到了与该组件完全相同的问题。

解决方案

EDIT:



已更新pdf预览的答案。该代码可在同一个插件中使用。



参考文献:@Michael在 https://stackoverflow.com/a/21732039/6347317



在上面的示例中,http POST的响应用于 new Blob([response]。在angular-file-upload库中, response将是 uploader.onAfterAddingFile函数中的 fileItem._file属性。您可以通过控制台日志来检查其中的数据,以了解



还请注意,如果未在chrome中启用PDf查看器,则必须使用以下命令启用它:> https://support.google.com/chrome/answer/6213030?hl=zh_CN



结束编辑



由于您提到您尝试过使用角度文件-upload库,我用它创建了一个插件:



http://plnkr.co/edit/jeYg5fIRaC9wuEYSNOux?p=info



HTML:

 <!DOCTYPE html> 
< html ng-app = plunker>
< head>
< meta charset = utf-8 />
< title> AngularJS Plunker< / title>
< script> document.write(’< base href =’+ document.location +’ />’));< / script>
< link rel = stylesheet href = http://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css />
< link rel = stylesheet href = style.css />
< script src = https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js>< / script>
< script data-require = angular.js@1.5.x src = https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js data-semver = 1.5.11>< / script>
< script src = http://netdna.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js< / script>
< script src = https://cdnjs.cloudflare.com/ajax/libs/angular-file-upload/2.5.0/angular-file-upload.min.js>< / script> ;
< script src = app.js>< / script>
< / head>

< body ng-controller = MainCtrl>
< div class = col-sm-4>

< h3>选择文件< / h3>

< div ng-show = uploader.isHTML5>
<!-3. nv-file-over uploader = link over-class = className->
< div class = well my-drop-zone style = width:300px nv-file-drop nv-file-over = uploader = uploader
filter = syncFilter >
< label>
单击此处或拖放文件
< input type = file style = visibility:hidden; nv-file-select nv-file-over = uploader = uploader
filter = syncFilter multiple />
< / label>
< div class = progress style = margin-bottom:0;>
< div class = progress-bar role = progressbar ng-style = {’width':uploader.queue [0] .progress +‘%’}>< / div>
< / div>
< div> {{uploader.queue [0] .file.name}}< / div>

< div ng-show = showAlert class = alert alert-warning alert-dismissable>
< a href =# class = close data-dismiss = alert aria-label = close>×< / a>
< strong>清除现有文件,然后再次上传!< / strong>
< / div>
< / div>

< / div>
< / div>

< / body>

< / html>

JS:

  var app = angular.module('plunker',['angularFileUpload']); 

app.controller('MainCtrl',function($ scope,FileUploader){
var uploader = $ scope.uploader = new FileUploader();

/ / FILTERS

//同步过滤器
uploader.filters.push({
name:'syncFilter',
fn:function(item / * {File | FileLikeObject} * /,选项){
console.log('syncFilter'+ this.queue.length);
返回this.queue.length< 1;
}
});

//异步过滤器
uploader.filters.push({
name:'asyncFilter',
fn:function(item / * {File | FileLikeObject} * /,选项,延迟){
console.log('asyncFilter');
setTimeout(deferred.resolve,1e3);
}
});


uploader.allowNewFiles = true;
uploader.filters.push({
name:'csvfilter',
fn:function(){
返回this.allowNewFiles;
}
});

//回调

uploader.onWhenAddingFileFailed = function(item / * {File | FileLikeObject} * /,filter,options){
console.info(' onWhenAddingFileFailed',项目,过滤器,选项);
$ scope.showAlert = true;
};


uploader.onAfterAddingFile = function(fileItem){

};
});

这很简单,我没有得到您提到的错误。我们实际上是在我们的一个项目中使用此库。我还添加了一个过滤器,以限制仅上传1个文件。



请检查此内容,并让我知道它的运行方式,或者您对代码有任何疑问。


I am trying to implement a simple file drag and drop functionality in Angular js/MVC.

I created a directive for the drag and drop.

(function (angular, undefined) {
    'use strict';

    angular.module('fileupload', [])
     .directive("myDirective", function ($parse) {
         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);

             var onImageDrop = $parse(attrs.onImageDrop);

             //When a file is dropped
             var loadFile = function (files) {
                 scope.uploadedFiles = files;
                 scope.$apply(onImageDrop(scope));
             };

             function dropHandler(angularEvent) {
                 var event = angularEvent.originalEvent || angularEvent;
                 var files = event.dataTransfer.files;
                 event.preventDefault();
                 loadFile(files)
             }

             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');
             }
         }
     });
}(angular));

This is the template

<div class="dropzone" data-my-Directive on-image-drop="$ctrl.fileDropped()">
Drag and drop pdf files here
</div>

This is my component code

(function (angular, undefined) {
    'use strict';

    angular.module('test', [])
        .component('contactUs', contactUs());

    function contactUs() {
        ContactUs.$inject = ['$scope', '$http'];
        function ContactUs($scope, $http) {
            var ctrl = this;
            ctrl.files = [];
         
            ctrl.services = {
                $scope: $scope,
                $http: $http,
            };
        }

        //file dropped
        ContactUs.prototype.fileDropped = function () {
            var ctrl = this;
            var files = ctrl.services.$scope.uploadedFiles;
            angular.forEach(files, function (file, key) {
                ctrl.files.push(file);
            });
        }


        return {
            controller: ContactUs,
            templateUrl: 'partials/home/contactus/'
        };
    }
}(angular));

Sometimes the drag and drop works absolutely fine without any issue. But some times I get the below issue and the drag and drop does not work and I get the black invalid cursor.

This issue is random and i do not see any errors in the console.

And I also tried other third party components like angular-file-upload https://github.com/nervgh/angular-file-upload and I am seeing the exact same issue with that component also.

解决方案

EDIT :

Answer updated for pdf preview. The code is available in the same plunker.

References : Excellent solution by @Michael at https://stackoverflow.com/a/21732039/6347317

In the example above, the response from the http POST is used in "new Blob([response]". In angular-file-upload library, the "response" would be "fileItem._file" property in "uploader.onAfterAddingFile" function. You can console log to check the data these have , so as to understand it better.

Also please note that if PDf viewer is not enabled in chrome, it has to be enabled using this: https://support.google.com/chrome/answer/6213030?hl=en

END EDIT

Since you mentioned that you tried with angular-file-upload library, i have created a plunker with it:

http://plnkr.co/edit/jeYg5fIRaC9wuEYSNOux?p=info

HTML:

<!DOCTYPE html>
    <html ng-app="plunker">
      <head>
        <meta charset="utf-8" />
        <title>AngularJS Plunker</title>
        <script>document.write('<base href="' + document.location + '" />');</script>
           <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
        <link rel="stylesheet" href="style.css" />
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
        <script data-require="angular.js@1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
        <script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-file-upload/2.5.0/angular-file-upload.min.js"></script>
        <script src="app.js"></script>
      </head>

      <body ng-controller="MainCtrl">
                      <div class="col-sm-4">

                        <h3>Select files</h3>

                        <div ng-show="uploader.isHTML5">
                            <!-- 3. nv-file-over uploader="link" over-class="className" -->
                          <div class="well my-drop-zone" style="width:300px" nv-file-drop nv-file-over="" uploader="uploader" 
                          filters="syncFilter">
                               <label>
                              Click here or Drag and Drop file
                                 <input type="file" style="visibility:hidden;" nv-file-select nv-file-over="" uploader="uploader" 
                                 filters="syncFilter" multiple/>
                                </label> 
                                  <div class="progress" style="margin-bottom: 0;">
                                  <div class="progress-bar" role="progressbar" ng-style="{ 'width': uploader.queue[0].progress + '%' }"></div>
                                  </div>
                                <div>{{uploader.queue[0].file.name}}</div>

                                  <div ng-show="showAlert" class="alert alert-warning alert-dismissable">
                                    <a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
                                     <strong>Clear the existing file before uploading again!!</strong> 
                                  </div>
                          </div>

                        </div>
                      </div>

      </body>

    </html>

JS:

var app = angular.module('plunker', ['angularFileUpload']);

app.controller('MainCtrl', function($scope,FileUploader) {
var uploader = $scope.uploader = new FileUploader();

        // FILTERS

        // a sync filter
        uploader.filters.push({
            name: 'syncFilter',
            fn: function(item /*{File|FileLikeObject}*/, options) {
                console.log('syncFilter' + this.queue.length);
                return this.queue.length < 1;
            }
        });

        // an async filter
        uploader.filters.push({
            name: 'asyncFilter',
            fn: function(item /*{File|FileLikeObject}*/, options, deferred) {
                console.log('asyncFilter');
                setTimeout(deferred.resolve, 1e3);
            }
        });


uploader.allowNewFiles = true;
uploader.filters.push({
  name:'csvfilter',
  fn: function() {
    return this.allowNewFiles;
}
});

        // CALLBACKS

        uploader.onWhenAddingFileFailed = function(item /*{File|FileLikeObject}*/, filter, options) {
            console.info('onWhenAddingFileFailed', item, filter, options);
            $scope.showAlert=true;
        };


        uploader.onAfterAddingFile = function(fileItem) {

  };
});

It is pretty straight forward and i dont get the error you mentioned. We are actually using this library in one of our Projects. I have also added a filter to restrict upload to only 1 file.

Please check this and let me know how it goes or if you have any doubts in the code.

这篇关于Angular js / MVC中的文件拖放功能不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆