2014-10-02 42 views
3

表單視圖:如何在AngularJS中上傳多部分表單?

 <form enctype="multipart/form-data" ng-submit="upload(file)"> 

      <input type="file" ng-model="modal.file" accept="image/gif" app-filereader /><br /> 

      <br> 

      <textarea name="description" placeholder="Description" ng-model="description" id="" cols="30" rows="10"></textarea> 

      <br> 

      <input type="hidden" name="user" ng-model="user" value="{{ user }}" /> 

      <br> 

      <input type="submit" value="Submit" class="network-sensitive button button-block button" /> 

     </form> 

指令:在我的服務

.directive('appFilereader', function(
$q 
){ 
    var slice = Array.prototype.slice; 

return { 
    restrict: 'A' 
    , require: '?ngModel' 
    , link: function(scope, element, attrs, ngModel){ 
     if(!ngModel) return; 

     ngModel.$render = function(){} 

     element.bind('change', function(e){ 
      var element = e.target; 

      $q.all(slice.call(element.files, 0).map(readFile)) 
      .then(function(values){ 
       if(element.multiple) ngModel.$setViewValue(values); 
       else ngModel.$setViewValue(values.length ? values[0] : null); 
      }); 

      function readFile(file) { 
       var deferred = $q.defer(); 

       var reader = new FileReader() 
       reader.onload = function(e){ 
        deferred.resolve(e.target.result); 
       } 
       reader.onerror = function(e) { 
        deferred.reject(e); 
       } 
       reader.readAsDataURL(file); 

       return deferred.promise; 
      } 

     }); 

    } 

}; 

}); 

上傳功能:

upload: function(file) { 
    var token = $window.sessionStorage.token; 

    var url = 'http://url.co/api/posts/creates'; 

    var $cache = $cacheFactory.get('$http'); 

    var deffered = $q.defer(); 

    var data = $cache.get(url); 

    if(!data) { 
     $http({ 
     url: url, 
     method: "POST", 
     params: { access_token: token }, 
     data: file, 
     headers: {'Content-Type': undefined }, 
     transformRequest: angular.identity 
     }).then(function(res) { 
     deffered.resolve(res); 
    }); 
    } else { 
    deffered.resolve(data); 
    } 

    return deffered.promise; 
    } 

我不包括因爲它只是中繼來自表單數據的控制器代碼服務的模式以及該部分的工作。

我遇到的問題是該文件被提交爲編碼數據(我的知識對二進制數據和blob等有點搖擺不定)。我的API(用Symfony2編寫)期望提交正常的文件,而不是數據字符串。

那麼如何將該二進制blob轉換爲我可以提交的圖像文件?或者我錯過了什麼?

回答

0

的問題是$ http服務,使用默認的內容類型爲應用/ JSON,並在你的情況下,它必須是應用程序/ x-WWW窗體-urlencoded 爲了解決這個問題,你可以使用以下指令:https://github.com/nervgh/angular-file-upload/wiki/Module-API,它還支持隨文件一起發送數據。

另一種形式給出是使用FORMDATA對象和XmlHttpRequest一起在你的指令,像這樣:

   var data = new FormData(); 
       var xhr = new XMLHttpRequest(); 
       data.append('file', files[i], files[i].name); 
       xhr.open('POST', scope.mseUploadFile); 
       xhr.onreadystatechange = function() { 
        if (xhr.readyState == 4 && xhr.status == 200) { 
         var result = xhr.responseText; 

         if (scope.callback) { 
          scope.$apply(function() { 
           scope.callback({ $data: result }); 
          }); 
         } 

        } 
        else if (xhr.readyState == 4 && xhr.status == 400) { 
         scope.$apply(function() { 
          if (scope.onError) { 
           scope.onError({ $error: xhr.responseText }); 
          } 
          handleError(xhr.responseText); 
         }); 

        } 
       }; 
       xhr.send(data); 
1

使用這個模塊https://github.com/danialfarid/angular-file-upload 是非常簡單易用。

例如:

var $file;//single file 
    $scope.sendFiles= function(){ 
    $upload.upload({ 
         url: yourUrl, 
         method: "POST", 
         data: { data: $scope.yourOtherObject }, 
         file: $file 
        }).success(function (data, status, headers, config) { 
         // file is uploaded successfully 
         console.log(data); 
         console.log("File upload SUCCESS"); 
        }).error(function (data, status) { 
         console.log("File upload FAILED"); 
        }); 
    } 

    $scope.onFileSelect = function ($files) { 
       for (var i = 0; i < $files.length; i++) { 
        $file = $files[i];//set a single file 
       } 
      }; 

HTML代碼

<input type="file" name="myfile" ng-file-select="onFileSelect($files)" /> 
<button ng-click='sendFiles()'>Send file</button> 
相關問題