视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Angular下H5多张上传图片的方法
2020-11-27 15:05:20 责编:小OO
文档


本文给大家分享在使用angular上传图片的功能,在开发过程中遇到很多问题,最终都解决了,今天小编给大家介绍下Angular下H5上传图片的方法(可多张上传),非常不错,需要的朋友参考下

最近做的项目中用到了angular下上传图片功能,在做的过程中遇到了许多问题,最终都得以解决

angular上传时和普通上传时过程差不多,只不过是要不一些东西转化为angular的东西。

1.ng-file-select,指令angular是没此功能的,其实也是转化成了change事件,不多说,直接上代码

angular.module('myApp')
.directive('ngFileSelect', [ '$parse', '$timeout', function($parse, $timeout) {
 return function(scope, elem, attr) {
 var fn = $parse(attr['ngFileSelect']);
 elem.bind('change', function(evt) {
 var files = [], fileList, i;
 fileList = evt.target.files;
 if (fileList != null) {
 for (i = 0; i < fileList.length; i++) {
 files.push(fileList.item(i));
 }
 }
 $timeout(function() {
 fn(scope, {
 $files : files,
 $event : evt
 });
 });
 });
 };
 }])

2.服务 上传文件前预览并压缩图片功能

//上传文件预览
angular.module('myServers',[])
 .factory('fileReader', ['$q', '$log', function($q, $log) {
 var dataURItoBlob = function(dataURI) { 
 // convert base/URLEncoded data component to raw binary data held in a string 
 var byteString; 
 if (dataURI.split(',')[0].indexOf('base') >= 0) 
 byteString = atob(dataURI.split(',')[1]); 
 else 
 byteString = unescape(dataURI.split(',')[1]); 
 // separate out the mime component 
 var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 
 // write the bytes of the string to a typed array 
 var ia = new Uint8Array(byteString.length); 
 for (var i = 0; i < byteString.length; i++) { 
 ia[i] = byteString.charCodeAt(i); 
 } 
 return new Blob([ia], { 
 type: mimeString 
 }); 
 }; 
 var onLoad = function(reader, deferred, scope,file) {
 return function() {
 scope.$apply(function() {
 var img = new Image();
 //前端压缩图片
 img.onload = function(){ 
 //resize the image using canvas 
 var canvas = document.createElement("canvas"); 
 var ctx = canvas.getContext("2d"); 
 var width = img.width; 
 var height = img.height; 
 var MAX_WIDTH = width>2500 ? width/2 : 2500; 
 var MAX_HEIGHT = height>2500 ? height/2 : 2500;
 if (width > height) { 
 if (width > MAX_WIDTH) { 
 height *= MAX_WIDTH / width; 
 width = MAX_WIDTH; 
 } 
 } else { 
 if (height > MAX_HEIGHT) { 
 width *= MAX_HEIGHT / height; 
 height = MAX_HEIGHT; 
 } 
 }
 canvas.width = width ; 
 canvas.height = height; 
 ctx.drawImage(img, 0, 0, width, height); 
 var dataURL = canvas.toDataURL('image/jpeg', 1);
 var blob = dataURItoBlob(dataURL); 
 if(blob.size > 2000 * 1024){
 dataURL = canvas.toDataURL('image/jpeg', .2);
 }else if(blob.size > 1000 * 1024){
 dataURL = canvas.toDataURL('image/jpeg', .5);
 }else{
 dataURL = canvas.toDataURL('image/jpeg', .8);
 }
 blob = dataURItoBlob(dataURL);
 deferred.resolve(blob);
 }
 img.src = URL.createObjectURL(file);
 });
 };
 };
 var onError = function(reader, deferred, scope) {
 return function() {
 scope.$apply(function() {
 deferred.reject(reader.result);
 });
 };
 };
 var onProgress = function(reader, scope) {
 return function(event) {
 scope.$broadcast("fileProgress", {
 total: event.total,
 loaded: event.loaded
 });
 };
 };
 var getReader = function(deferred, scope, file) {
 var reader = new FileReader();
 reader.onload = onLoad(reader, deferred, scope,file);
 reader.onerror = onError(reader, deferred, scope);
 reader.onprogress = onProgress(reader, scope);
 return reader;
 };
 var readAsDataURL = function(file, scope) {
 var deferred = $q.defer();
 var reader = getReader(deferred, scope,file);
 reader.readAsDataURL(file);
 return deferred.promise;
 };
 return {
 readAsDataUrl: readAsDataURL
 };
 }]);

这里说明一下,部分代码是参考别人的代码(http://blog.csdn.net/zx007fack/article/details/41073601),但是对其中内容做了修改,因为用原来的代码,如果不加前端压缩功能是正常的,前端压缩的话因为要用到canvas, 直接用reader.result在ios上图片的宽高拿到的直接是0,android上是可以的,具体原因不是很确定是不是base的问题,所以我又直接把file传了进来,然后用原生js的方法新建图片元素拿到宽高,再用Canvas进行压缩,最后转成blob,通过formData传给后台。

3.controller代码

//选择图片后执行的方法
 $scope.fileArr = [];
 $scope.imgSrcArr = [];var i = 0; //为ios上图片都为image时添加序号
 $rootScope.onFileSelect = function(files, event) {
 //预览上传图片开始
 $rootScope.startLoading();
 var $this = angular.element(event.target);
 angular.forEach(files, function(value, index) {
 var fileIn = value;
 var fileInName = fileIn.name;
 var fileType = fileInName.substring(fileInName.lastIndexOf(".") + 1, fileInName.length);
 //解决ios下所有图片都为image.jpg的bug
 if(fileIn) {
 fileInName = fileInName.split('.')[0] + i + '.' + fileType;
 i++;
 }
 attachvo.push({
 name: fileInName,
 type: fileType
 });
 fileReader.readAsDataUrl(fileIn, $scope)
 .then(function(result) {
 result.name = fileInName;
 $scope.fileArr.push(result);
 $scope.imgSrcArr.push(URL.createObjectURL(result));
              //每次上传后清空file框,确保每次都能调用change事件
 document.querySelector('.upload').reset();
 });
 $scope.$on('fileProgress', function(event, data) {
 if(data.total == data.loaded) {
 $timeout(function() {
 //上传图片结束
 $rootScope.endLoading();
 }, 200)
 }
 }); 
 });
 $rootScope.showAttachment = false;
 };return false;
 }

这里处理了下图片,在名字上加了序号,因为在ios上每次选择的图片名字都叫image,查找了很多资料,说是safari的bug,后面版本才会解决,暂时只能以这种方式解决了。循环是上传多张图片

3.html代码

<ul class="upload-view-ul">
 <li ng-repeat="src in imgSrcArr" class="pull-left" ng-click="delCurUpload(src)" 
 ng-class="{'row-last': (($index+1) % 5==0)}">
 <span>x</span>
 <em ng-if='nrc'>{{formData.attachvo[$index].attachmentType}}</em>
 <img ng-src="{{src}}">
 </li>
 <p class="attachment" pop-type-select ng-if="nrc">+</p>
 <p class="attachment" ng-if="!nrc">
 +
 <form class="upload">
 <input type="file" name="file[]" ng-file-select="onFileSelect($files, $event)" multiple>
 </form>
 </p>
 </ul>

4.顺便把formdata时代码贴一下,采用H5上传图片的方式

this.FormdataPost = function(pathUrl, formId, formData, files) {
 var fd = new FormData();
 fd.append('formId', formId);
 if(files && angular.isArray(files)) {
 files.forEach(function(item) {
 fd.append('file', item, item.name);
 });
 }
 fd.append('formData', angular.toJson(formData, true));
 var httpConfig = {
 headers: {
 'Authorization': 'Bearer ' + this.token,
 'Content-Type': undefined
 },
 transformRequest: angular.identity
 };
 return $http.post(rootUrl + pathUrl, fd, httpConfig).then(function(data) {
 return data;
 }).catch(function(error) {
 $rootScope.interfaceName = pathUrl;
 $rootScope.setNewWortStatus({
 status: error.status,
 errInfo: error.data && error.data.statusInfo || ''
 });
 return error;
 });
 }

思路有一点混乱,不知道讲清楚了没有,想起来再添加吧

下载本文
显示全文
专题