Po naciśnięciu przycisku wysyłania, zbiór plików ($scope.files
, może być tak mały, jak jeden plik, tyle, ile użytkownik chce) zostanie przesłany przez FormData
i XMLHttpRequest
w moim kanciastym funkcja $scope.uploadFiles
:AngularJS: status śledzenia każdego przesłanego pliku jednocześnie
$scope.uploadFiles = function() {
for (var i in $scope.files) {
var form = new FormData();
var xhr = new XMLHttpRequest;
// Additional POST variables required by the API script
form.append('destination', 'workspace://SpacesStore/' + $scope.currentFolderUUID);
form.append('contenttype', 'idocs:document');
form.append('filename', $scope.files[i].name);
form.append('filedata', $scope.files[i]);
form.append('overwrite', false);
xhr.upload.onprogress = function(e) {
// Event listener for when the file is uploading
$scope.$apply(function() {
var percentCompleted;
if (e.lengthComputable) {
percentCompleted = Math.round(e.loaded/e.total * 100);
if (percentCompleted < 1) {
// .uploadStatus will get rendered for the user via the template
$scope.files[i].uploadStatus = 'Uploading...';
} else if (percentCompleted == 100) {
$scope.files[i].uploadStatus = 'Saving...';
} else {
$scope.files[i].uploadStatus = percentCompleted + '%';
}
}
});
};
xhr.upload.onload = function(e) {
// Event listener for when the file completed uploading
$scope.$apply(function() {
$scope.files[i].uploadStatus = 'Uploaded!'
setTimeout(function() {
$scope.$apply(function() {
$scope.files[i].uploadStatus = '';
});
}, 4000);
});
};
xhr.open('POST', '/path/to/upload/script');
xhr.send(form);
}
}
problemem jest to, że var i
przyrosty w początkowej dla pętli dla każdego pliku, a kiedy ogień detektory zdarzeń, i
już zwiększany przeszłość zamierzonej wartości files[i]
potrzebne, tylko dokonania ostatniego w tablica. Używam .uploadStatus
jako środka do interaktywnego pokazywania postępu każdego pojedynczego pliku użytkownikowi, w związku z czym musiałbym mieć osobne detektory zdarzeń dla każdego elementu tablicy w $scope.files
. Jak przypisać i śledzić zdarzenia dla poszczególnych elementów tablicy w Angular?
UPDATE
mam przerobione dwa detektory zdarzeń, z niewielkim powodzeniem, ale ja wciąż przeżywa dziwne zachowanie:
xhr.upload.onprogress = (function(file) {
// Event listener for while the file is uploading
return function(e) {
$scope.$apply(function() {
var percentCompleted = Math.round(e.loaded/e.total * 100);
if (percentCompleted < 1) {
file.uploadStatus = 'Uploading...';
} else if (percentCompleted == 100) {
file.uploadStatus = 'Saving...';
} else {
file.uploadStatus = percentCompleted + '%';
}
});
}
})($scope.files[i]);
xhr.upload.onload = (function(file, index) {
// Event listener for when the file completed uploading
return function(e) {
$scope.$apply(function() {
file.uploadStatus = 'Uploaded!'
setTimeout(function() {
$scope.$apply(function() {
$scope.files.splice(index,1);
});
}, 2000);
});
}
})($scope.files[i], i);
.onprogress
wydaje się iść gładko , ale z niewielkimi zmianami wprowadzonymi do .onload
, widzę teraz dziwne zachowanie z dwukierunkowym wiązaniem AngularJS dla jego szablonów. dla każdego elementu w postaci $scope.files
jest podany status, z wykorzystaniem wspomnianej wcześniej właściwości .uploadStatus
. Teraz mam setTimeout
splice elementów z tablicy, za pomocą zmiennej i
, która jest przekazywana do funkcji self-execing. Co dziwne, przesyłanie ogranicza się do około 6 równoczesnych wysyłek naraz, co musi być problemem po stronie serwera, ale zauważyłem, że gdy elementy tablicy są łączone, szablon ng-repeat
działa dziwacznie w miejscu, w którym spliceruje . element, niekoniecznie taki, jaki powinien. Zauważyłem również, że często są wpisy, które nie są łączone po przekroczeniu progu 2000 milisekund.
Przypomina to pierwotny problem, w którym zmienna i
jest niewiarygodna w przypadku wywoływania przez detektory zdarzeń. Teraz przekazuję go do anonimowej, samoczynnie wykonującej funkcji .onload
, a splice używa jej do określenia, który element tablicy powinien usunąć, ale niekoniecznie usuwa poprawny, a często pozostawia inne elementy w tablicy, gdy powinien je usunąć.
Nie jestem pewien, jak rozwiązać problem, ale to było niesamowite przykładem działa kod XHR do wysyłania plików z kątowy. Awansuj dla siebie. –