Angularjs, как загрузить многостраничные данные формы и файл?
Я новичок в angular.js, но у меня есть хорошее понимание основ.
То, что я хочу сделать, это загрузить файл и некоторые данные формы в виде данных с несколькими формами. Я читал, что это не особенность angular, однако сторонние библиотеки могут это сделать. Я клонировал angular -file-upload через git, но я все еще не могу опубликовать простую форму и файл.
Может ли кто-нибудь указать пример, html и js, как это сделать?
Ответы
Ответ 1
Прежде всего
- Вам не нужны специальные изменения в структуре. Я имею в виду: теги ввода html.
<input accept="image/*" name="file" ng-value="fileToUpload"
value="{{fileToUpload}}" file-model="fileToUpload"
set-file-data="fileToUpload = value;"
type="file" id="my_file" />
Ответ 2
Это довольно просто копия этой демонстрационной страницы проектов и показывает загрузку одного файла в форме отправки с загрузкой.
(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
<form ng-submit="uploadFile()">
<div class="row">
<div class="col-md-12">
<input type="text" ng-model="model.fileDescription" />
<input type="number" ng-model="model.rating" />
<input type="checkbox" ng-model="model.isAGoodFile" />
<input type="file" ng-file-select="onFileSelect($files)">
<div class="progress" style="margin-top: 20px;">
<div class="progress-bar" progress-bar="uploadProgress" role="progressbar">
<span ng-bind="uploadProgress"></span>
<span>%</span>
</div>
</div>
<button button type="submit" class="btn btn-default btn-lg">
<i class="fa fa-cloud-upload"></i>
<span>Upload File</span>
</button>
</div>
</div>
</form>
EDIT: добавлена передача модели до сервера в сообщение файла.
Данные формы во входных элементах будут отправлены в свойстве данных сообщения и будут доступны как обычные значения формы.
Ответ 3
Более эффективно отправлять файлы напрямую.
Кодировка base64 из Content-Type: multipart/form-data
добавляет дополнительные 33% накладных расходов. Если сервер поддерживает это, более эффективно отправлять файлы напрямую:
Выполнение нескольких запросов $http.post
непосредственно из FileList
$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);
};
При отправке POST с Файловым объектом важно установить 'Content-Type': undefined
. Затем метод отправки XHR обнаружит объект File и автоматически установит тип содержимого.
Рабочая демонстрация директивы select-ng-files, которая работает с ng-model
1
Элемент <input type=file>
по умолчанию не работает с директивой ng-model. Требуется пользовательская директива:
angular.module("app",[]);
angular.module("app").directive("selectNgFiles", 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" select-ng-files ng-model="fileList" multiple>
<h2>Files</h2>
<div ng-repeat="file in fileList">
{{file.name}}
</div>
</body>
Ответ 4
Вы можете проверить этот метод для отправки изображения и формы данных в целом
<div class="form-group ml-5 mt-4" ng-app="myApp" ng-controller="myCtrl">
<label for="image_name">Image Name:</label>
<input type="text" placeholder="Image name" ng-model="fileName" class="form-control" required>
<br>
<br>
<input id="file_src" type="file" accept="image/jpeg" file-input="files" >
<br>
{{file_name}}
<img class="rounded mt-2 mb-2 " id="prvw_img" width="150" height="100" >
<hr>
<button class="btn btn-info" ng-click="uploadFile()">Upload</button>
<br>
<div ng-show = "IsVisible" class="alert alert-info w-100 shadow mt-2" role="alert">
<strong> {{response_msg}} </strong>
</div>
<div class="alert alert-danger " id="filealert"> <strong> File Size should be less than 4 MB </strong></div>
</div>
Angular код JS
var app = angular.module("myApp", []);
app.directive("fileInput", function($parse){
return{
link: function($scope, element, attrs){
element.on("change", function(event){
var files = event.target.files;
$parse(attrs.fileInput).assign($scope, element[0].files);
$scope.$apply();
});
}
}
});
app.controller("myCtrl", function($scope, $http){
$scope.IsVisible = false;
$scope.uploadFile = function(){
var form_data = new FormData();
angular.forEach($scope.files, function(file){
form_data.append('file', file); //form file
form_data.append('file_Name',$scope.fileName); //form text data
});
$http.post('upload.php', form_data,
{
//'file_Name':$scope.file_name;
transformRequest: angular.identity,
headers: {'Content-Type': undefined,'Process-Data': false}
}).success(function(response){
$scope.IsVisible = $scope.IsVisible = true;
$scope.response_msg=response;
// alert(response);
// $scope.select();
});
}
});