AngularJS:同时上传每个文件的跟踪状态
当按下一个提交button时,通过FormData
和XMLHttpRequest
在我的angular度函数$scope.uploadFiles
提交一个文件( $scope.files
,可以像一个文件一样多,像用户想要的那样)
$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); } }
问题是var i
在每个文件的初始for循环中增加,并且在事件监听器触发的时候, i
已经增加了所需的files[i]
值,只影响数组中的最后一个值。 我使用.uploadStatus
作为交互式显示每个文件到用户的进度的手段,因此我需要为$scope.files
每个数组元素分别设置事件监听$scope.files
。 我将如何分配和跟踪Angular中的单个数组元素的事件?
UPDATE
我重新修改了这两个事件的听众,并取得了一些成功,但我仍然经历着一些奇怪的行为:
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
似乎.onprogress
,但是对.onload
做了一些小的改动,现在我看到很多AngularJS的模板双向绑定的奇怪行为。 对于数组$scope.files
的每个$scope.files
,都会使用前面提到的.uploadStatus
属性给出一个状态。 现在我有setTimeout
拼接数组中的元素,通过i
variables传递给自执行函数。 奇怪的是,上传一次只能上传大约6个同时上传的文件,这一定是服务器端的问题,但是我注意到,当数组元素被拼接时,模板中的ng-repeat
在奇怪的地方拼接一个元素,不一定是它应该的。 我也注意到,在2000毫秒阈值命中后,经常有条目不能被拼接。
这让人联想到事件监听器触发时variablesi
不可靠的原始问题? 现在我将它传递给匿名自执行的.onload
函数,并且拼接使用它来确定它应该删除哪个数组元素,但是它不一定删除正确的数组元素,并且经常在数组中保留其他元素当它应该被删除。
传递给事件处理程序的索引引用原始数组中的索引。 每次成功调用splice
,数组的变化和索引都不再指向相同的东西。
$scope.files = ['a.jpg', 'b.jpg', 'c.jpg']; // $scope.files[1] = 'b.jpg' $scope.files.splice(1,1); // $scope.files = ['a.jpg', 'c.jpg'] // $scope.files[1] = 'c.jpg'
AngularJs 1.5.5通过为上传进度提供callback事件处理程序来改变方法。
参考 – 如何使用$ http或$资源在angularjs 1.5.5中使用eventHandlers和uploadEventHandlers跟踪进度?
var uploadData = new FormData(); uploadData.append('file', obj.lfFile); var fileData = angular.toJson({ 'FileName': obj.lfFile.name, 'FileSize': obj.lfFile.size }); uploadData.append('fileData', fileData) $http({ method: 'POST', url: vm.uploadPath, headers: { 'Content-Type': undefined, 'UserID': vm.folder.UserID, 'ComputerID': vm.folder.ComputerID, 'KeepCopyInCloud': vm.keepCopyInCloud, 'OverWriteExistingFile': vm.overwriteExistingFile, 'RootFileID': vm.folder.RootFileID, 'FileName': obj.lfFile.name, 'FileSize': obj.lfFile.size }, eventHandlers: { progress: function(c) { console.log('Progress -> ' + c); console.log(c); } }, uploadEventHandlers: { progress: function(e) { console.log('UploadProgress -> ' + e); console.log(e); } }, data: uploadData, transformRequest: angular.identity }).success(function(data) { console.log(data); }).error(function(data, status) { console.log(data); console.log(status); });