ionic中實現從相冊中選擇圖片並一次上傳多張圖片

在開發項目的時候須要在一次請求中可以上傳多張圖片,本覺得使用cordova的相關插件file-transer就能輕鬆搞定。可是真的想的太簡單了,cordova plugin的file-transer一次只能上傳一個文件,若是想要用循環的方式,就會再後臺產生多條記錄顯然不是咱們須要的。最後翻了不少博客後加上本身調試終於實現。css

<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;
        }
      });
    };

注意:
一、這裏從相冊選擇照片的時候,咱們能夠在options中設置照片最大數目,但僅限於一次調用時,意思就是若是想限制最終的照片數目爲6,maximumImagesCount設置爲6後,第一次選擇了5張,第二次又能夠選擇6張,最終是超過了咱們數目限制,因此這裏的num我是做爲num變量傳入的。
二、ios不支持maximumImagesCount,這就比較坑了,沒辦法只能在最終上傳的時候,提示用戶了
三、不用管是從相冊$cordovaImagePicker,仍是用拍照$cordovaCamera獲取的uri我都直接放到files這個數組中,在html中能夠直接展現
四、這邊其實最須要注意的仍是在dealFiles這個函數中,必須確保全部的圖片都使用window.resolveLocalFileSystemURL方法將本地選取的圖片轉爲Blob而後追加到FormData中去,而且要保證已經轉化追加完畢。(真機調試的時候,一直上傳圖片失敗,沒有加$q.defer雖然全部圖片都已經調用了resolveLocalFileSystemURL方法,可是尚未轉化添加到formdata中)
五、利用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。 html

參考文章:ios

一次上傳多個文件在angular和cordova開發的app中json

ionic2中選取相冊圖片並支持多附件上傳數組

AngularJs實現Multipart/form-data 文件的上傳promise

相關文章
相關標籤/搜索