2013-07-13 5 views
6

Sono stato provato per giorni. Supponendo che ho una forma come segue:Come caricare un file utilizzando AngularJs come nel modo tradizionale

<form ng-submit="create()" class="form-horizontal" enctype="multipart/form-data"> 
     <div class="control-group"> 
     <label class="control-label">name : </label> 
     <div class="controls"> 
      <input type="text" class="input-xlarge" ng-model="message.title" /> 
     </div> 
     </div> 
     <div class="control-group"> 
     <label class="control-label">avatar : </label> 
     <div class="controls"> 
      <input type="file" ng-model="message.avatar" name="message[avatar]" /> 
     </div> 
     </div> 
     <div class="well"> 
     <input class="btn btn-large btn-primary" type="submit" value="建立資料" /> 
     </div> 
    </form> 

Sto usando la gemma carrierwave per gestire il caricamento di file dietro la scena. Il mio controller è il seguente:

Tuttavia non funziona. Quello che intendo fare è creare un modulo e caricare tutto come nel vecchio modo, ma gli esempi che ho trovato come ng-upload, o come this post o jquery file upload, non soddisfano le mie necessità. C'è qualche esempio o codice di esempio per questo scopo? Grazie.

+1

Ecco un violino che gestisce il caricamento di alcuni file in angolare usando xhr se questo non è quello che stai cercando potresti fornire maggiori dettagli su ciò che vuoi dato che quello che hai trovato non lo è: http: //jsfiddle.net/danielzen/utp7j/ – shaunhusain

risposta

5

Penso che "come alla vecchia maniera" sarebbe di non usare Ajax, ma suppongo che non sia quello che intendi. :)

Il violino di @ shaunhusain è un buon esempio di come utilizzare lo FormData object per gestire il caricamento del file. E usando this site come riferimento, è possibile utilizzare transformRequest per incorporare l'oggetto FormData.

Mantenere il proprio codice di base $http, modificarlo in modo da aggiungere l'oggetto transform:

$scope.create = function(message){ 
var deferred = $q.defer(); 
$http({ 
    method: 'POST', 
    url: '/resources/messages', 
    data: message // your original form data, 
    transformRequest: formDataObject // this sends your data to the formDataObject provider that we are defining below. 
    headers: {'Content-Type': 'multipart/form-data'} 
}). 
success(function(data, status, headers, config){ 
    deferred.resolve(data); 
}). 
error(function(data, status, headers, config){ 
    deferred.reject(status); 
}); 
return deferred.promise; 
}; 

Creare una fabbrica che incorporerà manipolare i dati del modulo in un carico utile che posso mandare. Sarà scorrere i dati del modulo (tra cui file caricato) e restituire un object sender-friendly:

app.factory('formDataObject', function() { 
    return function(data) { 
     var fd = new FormData(); 
     angular.forEach(data, function(value, key) { 
      fd.append(key, value); 
     }); 
     return fd; 
    }; 
}); 

non ho ancora testato questo, ma dovrebbe funzionare out of the box.

+2

Ho dovuto impostare 'Content-Type' su' undefined'. Altrimenti il ​​limite non veniva impostato dal browser. – maartencls

+2

FormData non è supportato da IE9. C'è un modo per aggirare questo? –