按下提交按钮后,$scope.files通过FormData和XMLHttpRequest在我的angular函数中提交了一个文件数组(,可以少到一个文件,用户可以多得多)$scope.uploadFiles:
$scope.files
FormData
XMLHttpRequest
$scope.uploadFiles
$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。如何在Angular中为单个数组元素分配和跟踪事件?
var i
i
files[i]
.uploadStatus
更新
我对两个事件侦听器进行了重新设计,但都取得了一些成功,但是我仍然遇到奇怪的行为:
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似乎进展顺利,但是对做了一些小的更改.onload,我现在看到AngularJS的模板双向绑定有很多奇怪的行为。对于数组中$scope.files的每个元素,使用上述.uploadStatus属性给出状态。现在,我通过传递给自执行函数setTimeout的i变量来拼接数组中的元素。奇怪的是,现在一次上传最多只能同时进行6次上传,这肯定是服务器端的问题,但是我注意到随着数组元素被拼接,ng- repeat模板中的行为异常奇怪,它将拼接 一个 元素,不一定是应有的元素。我还注意到,在达到2000毫秒阈值后,通常不会对条目进行拼接。
.onprogress
.onload
setTimeout
ng- repeat
这使人想起了最初的问题,即i在整个事件侦听器的触发过程中引用变量时,变量不可靠?现在,我将其传递给匿名自执行.onload函数,并且拼接使用它来确定应删除的数组元素,但不一定删除正确的数组元素,并且在删除数组元素时通常将其保留在数组中应该删除它们。
在index原始数组中传递给事件处理程序参照指标。每次成功调用后splice,数组更改,索引不再指向同一事物。
index
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'