File upload with AngularJS and XHR(2)
by andredgusmao
HTML
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.js"></script>
<div ng-controller="UploadCtrl">
<input type="file" multiple ng-model="files" file-change>
<br><br>
Selected: {{ files.length }}
</div>
JavaScript
// Module
// ------
var upload = angular.module('upload', []);
// Directive
// ---------
upload.directive('fileChange', function () {
var linker = function ($scope, element, attributes) {
// onChange, push the files to $scope.files.
element.bind('change', function (event) {
var files = event.target.files;
$scope.$apply(function () {
for (var i = 0, length = files.length; i < length; i++) {
$scope.files.push(files[i]);
}
});
});
};
return {
restrict: 'A',
link: linker
};
});
// Factory
// -------
upload.factory('uploadService', ['$rootScope', function ($rootScope) {
return {
send: function (file) {
var data = new FormData(),
xhr = new XMLHttpRequest();
// When the request starts.
xhr.onloadstart = function () {
console.log('Factory: upload started: ', file.name);
$rootScope.$emit('upload:loadstart', xhr);
};
// When the request has failed.
xhr.onerror = function (e) {
$rootScope.$emit('upload:error', e);
};
// Send to server, where we can then access it with $_FILES['file].
data.append('file', file, file.name);
xhr.open('POST', '/echo/json');
xhr.send(data);
}
};
}]);
// Controller
// ----------
upload.controller('UploadCtrl', ['$scope', '$rootScope', 'uploadService', function ($scope, $rootScope, uploadService) {
// 'files' is an array of JavaScript 'File' objects.
$scope.files = [];
$scope.$watch('files', function (newValue, oldValue) {
// Only act when our property has changed.
if (newValue != oldValue) {
console.log('Controller: $scope.files changed. Start upload.');
for (var i = 0, length = $scope.files.length; i < length; i++) {
...