angularjs - imagenes - formularios en angular 5
AngularJS: ¿cómo implementar una simple carga de archivos con formulario multiparte? (8)
Quiero hacer una publicación simple en varias partes desde AngularJS a un servidor node.js, el formulario debe contener un objeto JSON en una parte y una imagen en la otra parte (actualmente estoy publicando solo el objeto JSON con $ recurso)
Pensé que debería comenzar con input type = "file", pero luego descubrí que AngularJS no puede vincularse a eso ...
todos los ejemplos que puedo encontrar son para crear plugins jQuery para arrastrar y soltar. Quiero una simple carga de un archivo.
Soy nuevo en AngularJS y no me siento cómodo escribiendo mis propias directivas.
Es más eficiente enviar un archivo directamente.
La codificación base64 de Content-Type: multipart/form-data
agrega un 33% adicional de gastos generales. Si el servidor lo admite, es más eficiente enviar los archivos directamente:
$scope.upload = function(url, file) {
var config = { headers: { ''Content-Type'': undefined },
transformResponse: angular.identity
};
return $http.post(url, file, config);
};
Al enviar un POST con un objeto File , es importante establecer ''Content-Type'': undefined
. El método de envío XHR detectará el objeto File y configurará automáticamente el tipo de contenido.
Para enviar varios archivos, consulte Hacer varias solicitudes de $http.post
directamente desde una lista de archivos
Pensé que debería comenzar con input type = "file", pero luego descubrí que AngularJS no puede vincularse a eso ...
El elemento <input type=file>
no funciona de forma predeterminada con la directiva ng-model . Necesita una directiva personalizada :
Demostración de trabajo de la directiva "entrada de archivos" que funciona con ng-model
1
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);
})
}
}
});
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
<h1>AngularJS Input `type=file` Demo</h1>
<input type="file" files-input ng-model="fileArray" multiple>
<h2>Files</h2>
<div ng-repeat="file in fileArray">
{{file.name}}
</div>
</body>
$http.post
con tipo de contenido multipart/form-data
Si uno debe enviar multipart/form-data
:
<form role="form" enctype="multipart/form-data" name="myForm">
<input type="text" ng-model="fdata.UserName">
<input type="text" ng-model="fdata.FirstName">
<input type="file" file-model ng-model="filesArray" multiple>
<button type="submit" ng-click="upload()">save</button>
</form>
$scope.upload = function() {
var fd = new FormData();
fd.append("data", angular.toJson($scope.fdata));
for (i=0; i<$scope.filesArray.length; i++) {
fd.append("file"+i, $scope.filesArray[i]);
};
var config = { headers: {''Content-Type'': undefined},
transformRequest: angular.identity
}
return $http.post(url, fd, config);
};
Al enviar un POST con la API de FormData , es importante establecer ''Content-Type'': undefined
. El método de envío XHR detectará el objeto FormData
y establecerá automáticamente el encabezado del tipo de contenido en multipart/form-data con el límite apropiado .
Acabo de escribir una directiva simple (de uno existente, por supuesto) para un cargador simple en AngularJs.
(El complemento exacto de jQuery uploader es https://github.com/blueimp/jQuery-File-Upload )
Un cargador simple usando AngularJs (con implementación CORS)
(Aunque el lado del servidor es para PHP, también puedes cambiarlo nodo)
Acabo de tener este problema. Entonces hay algunos enfoques. El primero es que los nuevos navegadores admiten el
var formData = new FormData();
Siga este enlace a un blog con información sobre cómo el soporte se limita a los navegadores modernos, pero de lo contrario resuelve completamente este problema.
De lo contrario, puede publicar el formulario en un iframe utilizando el atributo de destino. Cuando publique el formulario, asegúrese de establecer el objetivo en un iframe con su propiedad de visualización establecida en none. El objetivo es el nombre del iframe. (Solo para que sepas.)
espero que esto ayude
Me gustaría agregar una alternativa. Utilizando la carga de archivo angular. Puedes encontrar una explicación:
Puede encontrar una explicación detallada aquí: https://github.com/nervgh/angular-file-upload Un ejemplo: https://github.com/nervgh/angular-file-upload/tree/master/examples/simple
Puede cargar mediante $resource
asignando datos al atributo de parámetros de las actions
de recursos de esta manera:
$scope.uploadFile = function(files) {
var fdata = new FormData();
fdata.append("file", files[0]);
$resource(''api/post/:id'', { id: "@id" }, {
postWithFile: {
method: "POST",
params: fdata,
transformRequest: angular.identity,
headers: { ''Content-Type'': undefined }
}
}).postWithFile(fdata).$promise.then(function(response){
//successful
},function(error){
//error
});
};
Puede usar la directiva simple / liviana ng-file-upload . Admite arrastrar y soltar, progreso de archivos y carga de archivos para navegadores que no sean HTML5 con FileAPI flash shim
<div ng-controller="MyCtrl">
<input type="file" ngf-select="onFileSelect($files)" multiple>
</div>
JS:
//inject angular file upload directive.
angular.module(''myApp'', [''ngFileUpload'']);
var MyCtrl = [ ''$scope'', ''Upload'', function($scope, Upload) {
$scope.onFileSelect = function($files) {
Upload.upload({
url: ''my/upload/url'',
file: $files,
}).progress(function(e) {
}).then(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
});
}];
Sé que esta es una entrada tardía, pero he creado una directiva de carga simple. ¡Con lo cual puedes trabajar de inmediato!
<input type="file" multiple ng-simple-upload web-api-url="/api/post" callback-fn="myCallback" />
ng-simple-upload más en Github con un ejemplo utilizando la API web.
Una solución de trabajo real sin más dependencias que angularjs (probado con v.1.0.6)
html
<input type="file" name="file" onchange="angular.element(this).scope().uploadFile(this.files)"/>
Angularjs (1.0.6) no es compatible con ng-model en las etiquetas "input-file", por lo que debe hacerlo de forma nativa y pasar todos los archivos seleccionados (eventualmente) del usuario.
controlador
$scope.uploadFile = function(files) {
var fd = new FormData();
//Take the first selected file
fd.append("file", files[0]);
$http.post(uploadUrl, fd, {
withCredentials: true,
headers: {''Content-Type'': undefined },
transformRequest: angular.identity
}).success( ...all right!... ).error( ..damn!... );
};
La parte interesante es el tipo de contenido indefinido y el transformRequest: angular.identity que le dan a $ http la capacidad de elegir el "tipo de contenido" correcto y administrar el límite necesario al manejar datos multipartes.