Интеграция с загрузчиком файлов для angularjs
Существует ли хороший загрузчик файлов с хорошей интеграцией (директива) для AngularJS?
Я ищу что-то, что легко оформить и поддерживает перетаскивание HTML5 и т. Д.
Кто-то, вероятно, скажет, что легко использовать существующий загрузчик и интегрировать его в AngularJS - на что я скажу: если это легко, тогда кто-то должен был уже сделать это.
5 ответов
Я на самом деле катал свой загрузчик один раз... но только потому, что мне не понравился ни один из уже сделанных JQuery. К сожалению, это частная собственность, и я не могу опубликовать ее в Интернете... но... я могу показать вам, как использовать практически любой плагин JQuery от Angular:
Кто-то, вероятно, скажет, что легко использовать существующий загрузчик и интегрировать его в AngularJS - на что я скажу: если это легко, то кто-то должен был уже это сделать.
Давайте предположим, что у меня есть плагин jQuery, который работает, выбрав div и вызывая pluginUploadCall()
в теме...
app.directive('myJqueryPluginUploader', function() {
return {
restrict: 'A',
link: function(scope, elem, attr, ctrl) {
// elem is a jQuery lite object
// or a jQuery object if jQuery is present.
// so call whatever plugins you have.
elem.pluginUploadCall();
}
};
});
И вот как это будет использоваться.
<div my-jquery-plugin-uploader></div>
Angular действительно хорошо интегрируется с jQuery, поэтому любые плагины, работающие в jQuery, должны работать довольно легко в Angular. Единственная хитрость возникает, когда вы хотите сохранить Dependency Injection, чтобы вы могли поддерживать тестирование своего Angular App. JQuery не очень хорош в DI, поэтому вам, возможно, придется прыгнуть через несколько обручей.
Если вы хотите сделать свой собственный ролл, я могу сказать, что сделал что-то вроде этого:
app.directive('customUploader', function(){
return {
restrict: 'E',
scope: {},
template: '<div class="custom-uploader-container">Drop Files Here<input type="file" class="custom-uploader-input"/><button ng-click="upload()" ng-disabled="notReady">Upload</button></div>',
controller: function($scope, $customUploaderService) {
$scope.notReady = true;
$scope.upload = function() {
//scope.files is set in the linking function below.
$customUploaderService.beginUpload($scope.files);
};
$customUploaderService.onUploadProgress = function(progress) {
//do something here.
};
$customUploaderService.onComplete = function(result) {
// do something here.
};
},
link: function(scope, elem, attr, ctrl) {
fileInput = elem.find('input[type="file"]');
fileInput.bind('change', function(e) {
scope.notReady = e.target.files.length > 0;
scope.files = [];
for(var i = 0; i < e.target.files.length; i++) {
//set files in the scope
var file = e.target.files[i];
scope.files.push({ name: file.name, type: file.type, size: file.size });
}
});
}
});
куда $customUploaderService
будет пользовательский сервис, который вы создаете с Module.factory()
который использует $http
разместить файлы и проверить прогресс на сервере.
Я знаю, что это расплывчато, и мне жаль, что это все, что я могу предоставить, но я надеюсь, что это поможет.
РЕДАКТИРОВАТЬ: загрузка файла с помощью перетаскивания - это небольшая хитрость CSS, BTW... для Chrome и FF, вы просто помещаете в содержащий div... затем делаете что-то вроде этого:
<div class="uploadContainer">Drop Files Here<input type="file"/></div>
div.uploadContainer {
position: relative;
width: 600px;
height: 100px;
}
div.uploadContainer input[type=file] {
visibility: hidden;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
... теперь все, что вы добавляете в этот div, будет действительно удалено при загрузке файла, и вы можете сделать div таким, каким вы хотите.
Вы можете попробовать AngularJS.ngUpload.
Это решение без HTML5, которое использует невидимый iFrame для загрузки файлов. Так как он не использует HTML5, он работает в любом браузере!
Образец кода:
<form action='/server/upload/handler' ng-upload="callbackFunction">
<!-- other form inputs goes here -->
<input type="file" name="anyEasyName" />
<input type="submit" class="upload-submit" value="Submit" />
</form>
<div>{{uploadReport}}</div>
Любой html-элемент, который поддерживает событие click, может использоваться для отправки формы, помеченной директивой ngUpload, только такие элементы должны быть помечены классом css upload-submit (как в случае с input [type = submit] выше.
В приведенном ниже примере для отправки формы используется стиль div.
<form action='/server/upload/handler' ng-upload="callbackFunction">
<!-- other form inputs goes here -->
<input type="file" name="anyEasyName" />
<div style="cursor: pointer; padding: 5px" class="upload-submit">Submit</div>
</form>
<div>{{uploadReport}}</div>
Вы можете сделать так, чтобы ваш / server / upload / handler выплевывал действительный URL, чтобы {{uploadReport}} мог использоваться для установки src тега , например так:
<img ng-src={{uploadReport}} />
и увидеть загруженное изображение появиться сразу!
NgController для приведенных выше примеров:
var UploadCtrl = function ($scope) {
$scope.callbackFunction = function(contentOfInvisibleFrame) {
$scope.uploadReport = contentOfInvisibleFrame;
}
}
Директива ngUpload может быть зарегистрирована вашим модулем приложений AngularJS, а именно:
var mainApp = angular.module('MainApp', ["ngUpload", ...]);
и добавлен в ваш документ как:
<html ng-app="MainApp">
</html>
AngularJS.ngUpload работает в контексте ngController; и таким образом вы можете иметь как можно больше загрузчиков в одном ngController. Например:
<form action='/server/upload/handler' ng-upload="callbackFunction1">
<!-- other form inputs goes here -->
<input type="file" name="anyEasyName" />
<input type="submit" class="upload-submit" value="Submit" />
</form>
Server response: {{uploadReport1}}
<form action='/server/upload/handler' ng-upload="callbackFunction2">
<!-- other form inputs goes here -->
<input type="file" name="anotherEasyName" />
<input type="submit" class="upload-submit" value="Submit" />
</form>
Server response: {{uploadReport2}}
обслуживаться:
var UploadCtrl = function ($scope) {
$scope.callbackFunction1 = function(contentOfInvisibleFrame) {
$scope.uploadReport1 = contentOfInvisibleFrame;
}
$scope.callbackFunction2 = function(contentOfInvisibleFrame) {
$scope.uploadReport2 = contentOfInvisibleFrame;
}
}
Демонстрацию этой директивы для обработчика загрузки на основе NodeJS можно найти по адресу http://ng-upload.eu01.aws.af.cm/.
Образцы кодов ASP.Net MVC и NodeJS можно найти на веб-сайте проекта по адресу github.com/twilson63/ngUpload/tree/master/examples
Надеюсь это поможет.
Я собрал простую / легкую угловую директиву с polyfill для браузеров, не поддерживающих HTML5 FormData, здесь:
https://github.com/danialfarid/ng-file-upload
Вы можете отправить другой объект модели вместе с файлом на сервер. Вот демонстрационная страница:
http://angular-file-upload.appspot.com/
<script src="angular.min.js"></script>
<script src="ng-file-upload.js"></script>
<div ng-controller="MyCtrl">
<input type="text" ng-model="myModelObj">
<input type="file" ngf-select ng-model="files" >
</div>
контроллер:
Upload.upload({
url: 'my/upload/url',
data: {myObj: $scope.myModelObj},
file: $scope.files
}).then(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
});
Если вы хотите обрабатывать несколько файлов, попробуйте это
jQuery File Upload Angularjs wrap от оригинального автора (blueimp)
Я думаю, что это самый мощный загрузчик на данный момент.
Недавно я написал директиву, которая поддерживает загрузку нескольких файлов.
Пример использования:
<lvl-file-upload
auto-upload='false'
choose-file-button-text='Choose files'
upload-file-button-text='Upload files'
upload-url='http://localhost:3000/files'
max-files='10'
max-file-size-mb='5'
get-additional-data='getData(files)'
on-done='done(files, data)'
on-progress='progress(percentDone)'
on-error='error(files, type, msg)'/>
Вы можете найти код на github и документацию на моем блоге.