Angularjs como fazer upload de dados de formulários multipartes e um arquivo?

Sou iniciante no angular.js, mas tenho uma boa noção do básico.

O que estou procurando fazer é enviar um arquivo e alguns dados de formulário como dados de formulário de várias partes. Eu li que isso não é um recurso de angular, no entanto, bibliotecas de terceiros podem fazer isso. Eu clonei upload de arquivo angular via git, mas ainda não consegui postar um formulário simples e um arquivo.

Alguém por favor pode fornecer um exemplo, html e js de como fazer isso?

Em primeiro lugar

  1. Você não precisa de nenhuma alteração especial na estrutura. Quero dizer: tags de input html.
 

Isso é bonito deve apenas uma cópia da página de demonstração de projetos e mostra o upload de um único arquivo no formulário de envio com o progresso do upload.

 (function (angular) { 'use strict'; angular.module('uploadModule', []) .controller('uploadCtrl', [ '$scope', '$upload', function ($scope, $upload) { $scope.model = {}; $scope.selectedFile = []; $scope.uploadProgress = 0; $scope.uploadFile = function () { var file = $scope.selectedFile[0]; $scope.upload = $upload.upload({ url: 'api/upload', method: 'POST', data: angular.toJson($scope.model), file: file }).progress(function (evt) { $scope.uploadProgress = parseInt(100.0 * evt.loaded / evt.total, 10); }).success(function (data) { //do something }); }; $scope.onFileSelect = function ($files) { $scope.uploadProgress = 0; $scope.selectedFile = $files; }; } ]) .directive('progressBar', [ function () { return { link: function ($scope, el, attrs) { $scope.$watch(attrs.progressBar, function (newValue) { el.css('width', newValue.toString() + '%'); }); } }; } ]); }(angular)); 

HTML

 
%

EDIT: Adicionado passando um modelo até o servidor na postagem do arquivo.

Os dados do formulário nos elementos de input serão enviados na propriedade de dados do post e estarão disponíveis como valores de formulário normais.

É mais eficiente enviar os arquivos diretamente.

A codificação base64 do Content-Type: multipart/form-data adiciona uma sobrecarga extra de 33%. Se o servidor suportar, é mais eficiente enviar os arquivos diretamente:

Fazendo várias solicitações $http.post diretamente de uma lista de arquivos

 $scope.upload = function(url, fileList) { var config = { headers: { 'Content-Type': undefined }, transformResponse: angular.identity }; var promises = fileList.map(function(file) { return $http.post(url, file, config); }); return $q.all(promises); }; 

Ao enviar um POST com um object File , é importante definir 'Content-Type': undefined . O método de envio XHR detectará o object File e definirá automaticamente o tipo de conteúdo.


Demonstração de trabalho da diretiva “input de arquivos” que funciona com o ng-model 1

O elemento não trabalha por padrão com a diretiva ng-model . Precisa de uma diretiva personalizada :

 angular.module("app",[]); angular.module("app").directive("filesInput", function() { return { require: "ngModel", link: function postLink(scope,elem,attrs,ngModel) { elem.on("change", function(e) { var files = elem[0].files; ngModel.$setViewValue(files); }) } } }); 
   

AngularJS Input `type=file` Demo

Files

{{file.name}}