AngularJS: как реализовать простую загрузку файла с помощью многострочной формы?
Я хочу сделать простой многостраничный пост из AngularJS на сервер node.js,
форма должна содержать объект JSON в одной части и изображение в другой части,
(В настоящее время я отправляю только объект JSON с $resource)
Я решил, что должен начать с input type="file", но потом выяснил, что AngularJS не может привязываться к этому.
все примеры, которые я могу найти, предназначены для размывания плагинов jQuery для перетаскивания. Мне нужна простая загрузка одного файла.
Я новичок в AngularJS и не чувствую себя комфортно с написанием своих собственных директив.
Ответы
Ответ 1
Реальное рабочее решение без каких-либо других зависимостей, чем angularjs (проверено с v.1.0.6)
HTML
<input type="file" name="file" onchange="angular.element(this).scope().uploadFile(this.files)"/>
Angularjs (1.0.6) не поддерживает ng-модель в тегах "входного файла", поэтому вам нужно сделать это с помощью "нативного" способа, который передает все (в конечном итоге) выбранные файлы от пользователя.
контроллер
$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!... );
};
Прохладная часть - это тип контента undefined и идентификатор transformRequest: angular., которые дают при $http возможность выбора правильного "типа контента" и управления границей, необходимой при обработке многостраничных данных.
Ответ 2
Вы можете использовать простую/легкую ng-file-upload.
Он поддерживает drag & drop, ход файла и загрузку файлов для браузеров, не поддерживающих HTML5, с помощью прошивки FileAPI flash
<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);
});
}];
Ответ 3
У меня была эта проблема. Таким образом, существует несколько подходов. Во-первых, новые браузеры поддерживают
var formData = new FormData();
Следуйте этой ссылке в блоге с информацией о, как поддержка ограничена современными браузерами, но в остальном она полностью решает эту проблему.
В противном случае вы можете отправить форму в iframe с использованием целевого атрибута.
Когда вы публикуете форму, обязательно установите цель в iframe с свойством отображения, равным none.
Цель - имя iframe. (Только чтобы вы знали.)
Я надеюсь, что это поможет
Ответ 4
Я знаю, что это поздняя запись, но я создал простую директиву загрузки. Которые вы можете получить в кратчайшие сроки!
<input type="file" multiple ng-simple-upload web-api-url="/api/post" callback-fn="myCallback" />
ng-simple-upload подробнее о Github с примером, использующим веб-API.
Ответ 5
Вы можете загрузить через $resource
, назначив данные атрибуту params ресурса actions
следующим образом:
$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
});
};
Ответ 6
Эффективно отправлять файл напрямую.
base64 encoding Content-Type: multipart/form-data
добавляет дополнительные 33% накладных расходов. Если сервер поддерживает его, более эффективно отправлять файлы напрямую:
$scope.upload = function(url, file) {
var config = { headers: { 'Content-Type': undefined },
transformResponse: angular.identity
};
return $http.post(url, file, config);
};
При отправке POST с File object важно установить 'Content-Type': undefined
. метод отправки XHR затем обнаружит File object и автоматически установите тип содержимого.
Чтобы отправить несколько файлов, см. Выполнение нескольких $http.post
запросов непосредственно из списка файлов
Я решил, что должен начать с input type="file", но потом выяснил, что AngularJS не может привязываться к этому.
Элемент <input type=file>
по умолчанию не работает с директивой ng-model. Для этого требуется настраиваемая директива:
Рабочая демонстрация директивы "файлы-ввод", которая работает с 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>
Ответ 7
Я просто написал простую директиву (из уже существующей) для простого загрузчика в AngularJs.
(Точный плагин для загрузчика jQuery https://github.com/blueimp/jQuery-File-Upload)
Простой загрузчик с использованием AngularJs (с реализацией CORS)
(Хотя серверная сторона для PHP, вы можете просто изменить ее и node)
Ответ 8
Я хотел бы добавить альтернативу. Использование angular файла-загрузки.
Вы можете найти объяснение:
Подробное объяснение можно найти здесь: https://github.com/nervgh/angular-file-upload Пример: https://github.com/nervgh/angular-file-upload/tree/master/examples/simple