angularjs 实现 文件拖拽,缩略图显示

成果图:

main-hugeScreen.html

<div class="hbox hbox-auto-xs hbox-auto-sm" ng-controller="HugeScreenCtrl">
    <!--div ng-controller="HugeScreenCtrl">
    <div class="col w-lg bg-light b-r bg-auto">
        <div class="wrapper-md dker b-b">
            <h3 class="m-n font-thin">选择文件</h3>
        </div>
        <div class="wrapper-md">
            <p>多个文件</p>
            <input type="file" multiple/>
            <p class="m-t-md">单个文件</p>
            <input type="file"/>
        </div>
    </div>
    <div>
        <input type="file" file-model="myFile" multiple/>
        <button ng-click="uploadFile()">upload me</button>
    </div>
</div-->
    <div class="col w-lg bg-light b-r bg-auto">
        <div class="wrapper-md dker b-b">
            <h3 class="m-n font-thin">Select files</h3>
        </div>
        <div class="wrapper-md">
            <div ng-show="true" class="m-b-md">
                <!-- 3. nv-file-over uploader="link" over-class="className" -->
                <div file-dropzone="[image/png, image/jpeg, image/gif]"
                     files="myFile" over-class='b-danger' data-max-file-size="3" class="b-a b-2x b-dashed wrapper-lg bg-white text-center m-b">
                    Base drop zone
                </div>

                <!-- Example: nv-file-drop="" uploader="{Object}" options="{Object}" filters="{String}" -->
                <div>
                    <div file-dropzone="[image/png, image/jpeg, image/gif]"
                         files="myFile"  over-class='b-info' data-max-file-size="3" active="redColorActive" class="b-a b-2x b-dashed wrapper-lg lter text-center" >
                        Another drop zone with its own settings
                    </div>
                </div>
            </div>

            <!-- Example: nv-file-select="" uploader="{Object}" options="{Object}" filters="{String}" -->
            <p>Multiple</p>
            <input type="file" file-model="myFile" multiple/>

            <p class="m-t-md">Single</p>
            <input type="file" file-model="myFile"/>
        </div>
    </div>
    <div class="col">
        <div class="wrapper-md bg-light dk b-b">
            <span class="pull-right m-t-xs">Queue length: <b class="badge bg-info">{{myFile.length}}</b></span>
            <h3 class="m-n font-thin">Upload queue</h3>
        </div>
        <div class="wrapper-md">
            <table class="table bg-white-only b-a">
                <thead>
                <tr>
                    <th width="30%">缩略图</th>
                    <th width="30%">Name</th>
                    <th ng-show="true">Size</th>
                    <th ng-show="true">Progress</th>
                    <th>Status</th>
                    <th>Actions</th>
                </tr>
                </thead>
                <tbody>
                <tr ng-repeat="item in myFile">
                    <!--td><img ng-src={{item.stream}}/></td-->
                    <td><img ng-src={{item.stream}} style="max- 200px; max-height: 200px"/></td>
                    <td><strong>{{ item.file.name }}</strong></td>
                    <td ng-show="true" nowrap>{{ item.file.size/1024/1024|number:2 }} MB</td>
                    <td ng-show="true">
                        <div class="progress progress-sm m-b-none m-t-xs">
                            <div class="progress-bar bg-info" role="progressbar" ng-style="{ 'width': item.progress + '%' }"></div>
                        </div>
                    </td>
                    <td class="text-center">
                        <span ng-show="item.isSuccess" class="text-success"><i class="glyphicon glyphicon-ok"></i></span>
                        <span ng-show="item.isCancel" class="text-warning"><i class="glyphicon glyphicon-ban-circle"></i></span>
                        <span ng-show="item.isError" class="text-danger"><i class="glyphicon glyphicon-remove"></i></span>
                    </td>
                    <td nowrap>
                        <button type="button" class="btn btn-default btn-xs" ng-click="item.upload(item)" ng-disabled="item.isReady || item.isUploading || item.isSuccess">
                            Upload
                        </button>
                        <button type="button" class="btn btn-default btn-xs" ng-click="removeItem($index)">
                            Remove
                        </button>
                    </td>
                </tr>
                </tbody>
            </table>
            <div>
                <div>
                    <p>Queue progress:</p>
                    <div class="progress bg-light dker" style="">
                        <div class="progress-bar progress-bar-striped bg-info" role="progressbar" ng-style="{ 'width': allprogress   + '%' }"></div>
                    </div>
                </div>
                <button type="button" class="btn btn-addon btn-success" ng-click="uploadAllfiles(allprogress)">
                    <i class="fa fa-arrow-circle-o-up"></i> Upload all
                </button>
                <button type="button" class="btn btn-addon btn-warning" ng-click="cancelAll()" ng-disabled="!myFile.isUploading">
                    <i class="fa fa-ban"></i> Cancel all
                </button>
                <button type="button" class="btn btn-addon btn-danger" ng-click="clearQueue()" ng-disabled="!myFile.length">
                    <i class="fa fa-trash-o"></i> Remove all
                </button>
                <p class="text-muted m-t-xl">Note: upload.php file included, files will be uploaded to "src/js/controllers/uploads".</p>
            </div>
            <div>
                <table><thead><tr><th>缩略图</th></tr></thead><tbody>
                <tr ng-repeat="item in image track by $index">
                <td>
                    <img ng-src={{item}} />
                </td>
                </tr>
                </tbody></table>

               <!-- <span class="file-name">{{imageFileName}}</span>-->
            </div>
        </div>
    </div>
</div>

bjt-imageload-service.js

/**
 * Created by chaiqiaozhen on 10/6/15.
 */
app.service('fileReader', function ($q) {

    var fileReader = this;
        fileReader.onLoad = function(file, reader,deferred, scope) {
            return function () {
                scope.$apply(function () {
                    var ret = {
                        srcfile: file,
                        stream: reader.result
                    };
                    deferred.resolve(ret);
                });
            };
        };

    fileReader.onError = function (reader, deferred, scope) {
            return function () {
                scope.$apply(function () {
                    deferred.reject(reader.result);
                });
            };
        };

    fileReader.onProgress = function(reader, scope) {
            return function (event) {
                scope.$broadcast("fileProgress",
                    {
                        total: event.total,
                        loaded: event.loaded
                    });
            };
        };

    fileReader.getReader = function(file,deferred, scope) {
            var reader = new FileReader();
            reader.onload = fileReader.onLoad(file, reader,deferred, scope);
            reader.onerror = fileReader.onError(reader, deferred, scope);
            reader.onprogress = fileReader.onProgress(reader, scope);
            return reader;
        };

    fileReader.readMyAsDataURL = function (file, scope) {
            var deferred = $q.defer();

            var reader = fileReader.getReader(file, deferred, scope);
            reader.readAsDataURL(file);

            return deferred.promise;
        };

    });

hugeScreen-service.js

app.directive('fileDropzone', ['$bjtHttpService','fileReader',function($bjtHttpService,fileReader) {
    return {
        restrict: 'A',
        scope: {
            files: '=',
            overClass: '='
        },
        link: function(scope, element, attrs) {
            var checkSize, isTypeValid, processDragOverOrEnter, validMimeTypes,getDataTransfer,addfile;
            var fileList = [];
            addfile = function(item){
                fileList[fileList.length] = item;
            }
            getDataTransfer = function(event) {
                var dataTransfer;
                return dataTransfer = event.dataTransfer || event.originalEvent.dataTransfer;
            };
            processDragOverOrEnter = function(event) {
                if (event != null) {
                    event.preventDefault();
                }
                getDataTransfer(event).effectAllowed = 'copy';
                element.addClass(attrs.overClass);

              //  console.log(element);
                return false;
            };
            validMimeTypes = attrs.fileDropzone;
            checkSize = function(size) {
                var _ref;
                if (((_ref = attrs.maxFileSize) === (void 0) || _ref === '') || (size / 1024) / 1024 < attrs.maxFileSize) {
                    return true;
                } else {
                    alert("File must be smaller than " + attrs.maxFileSize + " MB");
                    return false;
                }
            };
            isTypeValid = function(type) {
                if ((validMimeTypes === (void 0) || validMimeTypes === '') || validMimeTypes.indexOf(type) > -1) {
                    return true;
                } else {
                    alert("Invalid file type.  File must be one of following types " + validMimeTypes);
                    return false;
                }
            };
            element.bind('dragover', processDragOverOrEnter);
            element.bind('dragenter', processDragOverOrEnter);
            return element.bind('drop', function(event) {
                var files;
                if (event != null) {
                    event.preventDefault();
                }
                element.removeClass(attrs.overClass);
                fileList = [];
                files = getDataTransfer(event).files;
                for(var i = 0; i < files.length; i++){
                    if(!isTypeValid(files[i].type))
                        return false;
                    if(!checkSize(files[i].size))
                       return false;
                  /*  var reader = new FileReader();
                    reader.onload = function(reader,evt){
                        console.log(reader);
                    };
                    reader.readAsDataURL(files[i]);*/
                  /*  fileReader.readMyAsDataURL(files[i],scope).then(
                        function(ret){
                            console.log(ret);
                    });*/
                   fileReader.readMyAsDataURL(files[i], scope)
                        .then(function(ret) {
                            var file = {
                                isSuccess: false,
                                isCancel: false,
                                isError: false,
                                progress: 0,
                                isReady: false,
                                isUploading: false,
                                file: ret.srcfile,
                                stream: ret.stream,
                                upload: function (item) {

                                    var options = {
                                        headers: {'Content-Type': undefined},
                                        callbackError: function(args,data){
                                            item.isError = true;
                                        },
                                        callbackSuccess: function(args,data){
                                            item.isSuccess = true;
                                            item.progress = 100;
                                            console.log(this.isSuccess);
                                        }
                                    };
                                    var addOptions = {
                                        transformRequest: angular.identity
                                    };
                                    var fd = new FormData();
                                    fd.append('file', this.file);
                                    $bjtHttpService.$post('demo/file/upload',fd,options,addOptions);
                                }
                            };
                            addfile(file);
                        });
                }
                scope.files = fileList;
                return false;
            });
        }
    };
}]);
app.directive('fileModel',  ['$parse', '$bjtHttpService', function ($parse, $bjtHttpService) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;
            var filelist = [];
            element.bind('change', function(){
                scope.$apply(function(){
                    for(var i = 0; i < element[0].files.length; i++){
                        var file = {
                            isSuccess: false,
                            isCancel: false,
                            isError: false,
                            progress: 0,
                            isReady: false,
                            isUploading: false,
                            file: element[0].files[i],
                            fileStream: null,
                            upload: function (item) {

                                var options = {
                                    headers: {'Content-Type': undefined},
                                    callbackError: function(args,data){
                                        item.isError = true;
                                    },
                                    callbackSuccess: function(args,data){
                                        item.isSuccess = true;
                                        item.progress = 100;
                                        console.log(this.isSuccess);
                                    }
                                };
                                var addOptions = {
                                    transformRequest: angular.identity
                                };
                                var fd = new FormData();
                                fd.append('file', this.file);
                                $bjtHttpService.$post('demo/file/upload',fd,options,addOptions);
                            }
                        };
                        filelist[i] = file;
                    }
                    
                    modelSetter(scope, filelist);
                });
            });
        }
    };
}]);

app.controller('HugeScreenCtrl', ['$scope', 'fileReader', function($scope, fileReader) {


    $scope.allprogress=0;
    $scope.myFile = '';
    $scope.image= null;
    $scope.imageFileName = '';
    $scope.redColorActive = 'false';//'b-danger';
    $scope.removeItem = function(index){
        $scope.myFile.splice(index, 1);
    };
    $scope.getNotUploadedItems = function () {
        var files = [];
        for(var i = 0, j = 0; i < $scope.myFile.length; i++){
            if(!$scope.myFile[i].isSuccess)
                files[j++] = $scope.myFile[i];
        }
        return files;
    };
    $scope.getImage = function(item){
        fileReader.readMyAsDataURL(item, $scope)
            .then(function(result) {
                return result;
          });
    };
    $scope.uploadAllfiles = function(){
        $scope.allprogress = 0.0;
        console.log($scope.allprogress);

        var percent = 0;
        if($scope.myFile.length > 0)
            percent = 100/$scope.myFile.length;
        console.log(percent);
        for( var i = 0; i < $scope.myFile.length; i++) {
            if($scope.myFile[i].isSuccess)
                $scope.allprogress = $scope.allprogress+ percent;
            else{
                $scope.myFile[i].upload($scope.myFile[i]);
                if($scope.myFile[i].isSuccess)
                    $scope.allprogress = $scope.allprogress+ percent;
            }
            console.log($scope.allprogress);
        }
    };
}]);
原文地址:https://www.cnblogs.com/dorothychai/p/4862248.html