ionic中实现从相册中选择图片并一次上传多张图片

前端之家收集整理的这篇文章主要介绍了ionic中实现从相册中选择图片并一次上传多张图片前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在开发项目的时候需要在一次请求中能够上传多张图片,本以为使用cordova的相关插件file-transer就能轻松搞定。但是真的想的太简单了,cordova plugin的file-transer一次只能上传一个文件,如果想要用循环的方式,就会再后台产生多条记录显然不是我们需要的。最后翻了很多博客加上自己调试终于实现。

<div class="item row row-wrap">
        <div ng-repeat="item in files" class="col col-25">
          <div class="pos-relative level-center w60 h60">
            <img ng-src="{{item}}">
            <i ng-click="deleteFile(item)" class="icon ion-close-circled pos-absolute deleteFile"></i>
          </div>
        </div>

        <div ng-if="files.length < 6" ng-click="showActionSheet()" class="col col-25">
          <div class="text-align-center level-center pt5 w60 h60" style="border: 1px solid #b3b3b3;">
            <i class="icon ion-plus-round font30"></i>
            <p ng-bind="i18n.upload_accessory_btn" class="text-align-center font12"></p>
          </div>
        </div>

      </div>
function dealFiles(imageAry) {
      $ionicLoading.show();
      const deferred = $q.defer(),promise = _.map(imageAry,(item,key) => {
          const def = $q.defer();  // 这里再次使用$q.defer为了确保所有图片已经转化完毕
          window.resolveLocalFileSystemURL(item,fileEntry => {
            fileEntry.file(file => {
              let reader = new FileReader();
              reader.onloadend = e => {
                const the_file = new Blob([e.target.result ],{ type: file.type} );
                imgData.append("files" + key,the_file,file.name);
                def.resolve(item);
              };
              reader.readAsArrayBuffer(file);
            });
          });
          return def.promise;
        });

      $q.all(promise).then(result => {
        deferred.resolve(result);
      }).catch(reason => {
        deferred.reject(reason);
      });
      return deferred.promise;
    }

 function openImages(num) {
      const options = {
        maximumImagesCount: num,width: 600,height: 500,quality: 100
      };
      $cordovaImagePicker.getPictures(options)
        .then(results => {
          $scope.files = _.concat($scope.files,results);
        },error => {
          console.log(error);
        });
    }
    

 function takePhoto() {
      const options = {
        quality: 100,destinationType: Camera.DestinationType.PHOTOLIBRARY,sourceType: Camera.PictureSourceType.CAMERA,encodingType: Camera.EncodingType.JPEG,targetWidth: 600,targetHeight: 500
      };
      $cordovaCamera.getPicture(options).then(imageURI => {
        $scope.files.push(imageURI);
      }).catch(error => {
        console.log(error);
      });
    }

$scope.files = [];

$scope.uploadFiles = data => {
      dealFiles($scope.files).then(() => {
      //添加调用接口的的参数
        imgData.append("id",data);
        imgData.append("sid",$scope.userInfo.sid);
        $http.post(CONFIG.url.upload,imgData,{
          headers: {"Content-Type": undefined },transformRequest: angular.identity
        }).success(() => {
          $ionicLoading.hide();
         console.log("上传成功");
        }).error(() => {
          $ionicLoading.hide();
          console.log("请重新上传");
        });
      } );
    };
    
    
 $scope.showActionSheet = () => {
      const maxImgNum = 6,imageNum = maxImgNum - $scope.files.length;
      $ionicActionSheet.show({
        buttons: [
          {text: "拍照"},{text: "从相册中选择"}
        ],cancelText: "取消",cssClass: "touched",cancel() {

        },buttonClicked(index) {
          if (index) {
            openImages(imageNum);
          } else {
            takePhoto();
          }
          return true;
        }
      });
    };

注意:
1、这里从相册选择照片的时候,我们可以在options中设置照片最大数目,但仅限于一次调用时,意思就是如果想限制最终的照片数目为6,maximumImagesCount设置为6后,第一次选择了5张,第二次又可以选择6张,最终是超过了我们数目限制,所以这里的num我是作为num变量传入的。
2、ios不支持maximumImagesCount,这就比较坑了,没办法只能在最终上传的时候,提示用户
3、不用管是从相册$cordovaImagePicker,还是用拍照$cordovaCamera获取的uri我都直接放到files这个数组中,在html中可以直接展示
4、这边其实最需要注意的还是在dealFiles这个函数中,必须确保所有的图片都使用window.resolveLocalFileSystemURL方法将本地选取的图片转为Blob然后追加到FormData中去,并且要保证已经转化追加完毕。(真机调试的时候,一直上传图片失败,没有加$q.defer虽然所有图片都已经调用了resolveLocalFileSystemURL方法,但是还没有转化添加到formdata中)
5、利用angular实现post请求的时候,需要设置 headers: {"Content-Type": undefined },transformRequest: angular.identity
通过anjularjs的http请求来上传文件的,所以要让当前的request成为一个Multipart/form-data请求,anjularjs对于post和get请求默认的Content-Type header 是application/json。通过设置‘Content-Type’: undefined,这样浏览器不仅帮我们把Content-Type 设置为 multipart/form-data,还填充上当前的boundary,如果你手动设置为: ‘Content-Type’: multipart/form-data,后台会抛出异常:the current request boundary parameter is null。

参考文章

链接描述

链接描述

链接描述

猜你在找的Angularjs相关文章