AngularJS: Hochladen von Dateien mit $ resource (solution)
Ich bin mit AngularJS zur Interaktion mit einem RESTful
webservice, mit $resource
zu abstrahieren, die verschiedenen Entitäten. Einige dieser Entitäten sind die Bilder, so brauche ich, um der Lage sein, die save
Aktion von $resource
"Objekt" zu senden, sowohl binäre Daten und text-Feldern innerhalb der gleichen Anfrage.
Wie kann ich mithilfe von AngularJS ist $resource
- Dienst zum senden von Daten und das hochladen von Bildern zu einem restful webservice in einem einzigen POST
Anfrage?
InformationsquelleAutor der Frage juandemarco | 2014-01-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Habe ich gesucht weit und breit, während ich verpasst haben könnte, konnte ich nicht finden, eine Lösung für dieses problem: hochladen von Dateien mit einem $Ressource-Aktion.
Lassen Sie uns dieses Beispiel: unsere Rest-service ermöglicht uns den Zugriff auf die Bilder, indem Sie Anfragen an die
/images/
Endpunkt. JederImage
hat einen Titel, eine Beschreibung und der Pfad zeigt auf die Bild-Datei. Mithilfe der RESTful-Dienst, wir können alle von Ihnen (GET /images/
), ein einziger (GET /images/1
) oder hinzufügen (POST /images
). Angular ermöglicht es uns, verwenden Sie $resource service zum ausführen dieser Aufgabe leicht, aber nicht für den Datei-Upload - dies ist die Voraussetzung für die Dritte Aktion - out of the box (und scheinen Sie nicht zu sein Planung auf die Unterstützung es jederzeit schnell). Wie, dann würden wir gehen über die Verwendung des sehr handlichen $resource service, wenn Sie können nicht mit file-uploads? Es stellt sich heraus, es ist ganz einfach!Werden wir verwenden Sie Datenbindung verwenden, weil es eines der großartigen features von AngularJS. Wir haben die folgenden HTML-Formular:
Wie Sie sehen können, gibt es zwei text -
input
Felder der gebundenen jeweils um eine Eigenschaft eines einzelnen Objektes, die ich genannt habenewImage
. Die Dateiinput
ist gebunden sowie an eine Eigenschaft desnewImage
Objekt, aber dieses mal habe ich eine benutzerdefinierte Richtlinie gerade von hier. Diese Richtlinie macht es so, dass jedes mal, wenn der Inhalt der Dateiinput
verpasst, ein FileList-Objekt wird innerhalb der gebundenen Eigenschaft anstelle einesfakepath
(das wäre Eckigen standard-Verhalten).Controller-code ist der folgende:
(In diesem Fall ich bin mit einem NodeJS-server auf meinem lokalen Rechner auf port 3000, und die Antwort ist ein json-Objekt mit einer
status
Bereich und eine optionaledata
Feld).Damit der Datei-upload zu arbeiten, wir müssen Sie nur richtig konfigurieren, den $http-service, zum Beispiel innerhalb der .config rufen Sie auf der app-Objekt. Konkret brauchen wir für die Transformation der Daten der einzelnen post-request an ein FormData-Objekt so, dass es an den server geschickt in das richtige format:
Den
Content-Type
- header gesetzt ist, umundefined
da es manuell zumultipart/form-data
würde nicht die Grenze Wert, und der server würde nicht in der Lage sein, um eine Analyse der request korrekt.Das ist es. Jetzt können Sie
$resource
zusave()
Objekte, die sowohl die standard-Daten-Felder und-Dateien.WARNUNG Das hat einige Einschränkungen:
Wenn Ihr Modell "embedded" - Dokumente, wie
{
title: "A title",
attributes: {
fancy: true,
colored: false,
nsfw: true
},
image: null
}
dann müssen Sie umgestalten, die transformRequest Funktion entsprechend. Könnte man zum Beispiel
JSON.stringify
verschachtelte Objekte, vorausgesetzt, Sie können analysieren Sie am anderen EndeEnglisch ist nicht meine Hauptsprache, also, wenn meine Erklärung ist unklar Sag es mir und ich werde versuchen, das zu formulieren.:)
Ich hoffe das hilft, cheers!
EDIT:
Wie bereits von @davideine weniger invasive Lösung wäre die Definition dieses Verhalten nur für diejenigen, die
$resource
s, die es wirklich benötigen, und nicht zu verwandeln und jeden Wunsch von AngularJS. Sie können das tun, indem Sie Ihre$resource
wie diese:Als für den Kopf, sollten Sie eine, die Ihren Anforderungen genügt. Das einzige, was Sie angeben müssen ist die
'Content-Type'
Eigenschaft mit der Einstellungundefined
.InformationsquelleAutor der Antwort juandemarco
Kleinste und am wenigsten invasive Lösung senden
$resource
Anfragen mitFormData
ich fand dies sein:InformationsquelleAutor der Antwort timetowonder
Ich kam mit dieser Funktionalität zu konvertieren (oder Anhängen) Formular-Daten in ein FormData-Objekt. Es könnte wahrscheinlich sein verwendet als Dienst.
Die Logik unten drinnen sein sollte entweder ein
transformRequest
oder in$httpProvider
Konfiguration, oder kann verwendet werden als ein service. In irgendeiner WeiseContent-Type
header muss auf NULL gesetzt werden, und dies unterscheidet sich je nach Kontext Sie diese Logik. Zum Beispiel in einemtransformRequest
option bei der Konfiguration einer Ressource zu tun:oder wenn Sie die Konfiguration
$httpProvider
werden, könnte die Methode bereits in der Antwort oben.In dem Beispiel unten, die Logik, die sich innerhalb einer
transformRequest
- Methode für eine Ressource.Also mit diesem, die Sie tun können, die folgende ohne Probleme:
InformationsquelleAutor der Antwort Parziphal