按下提交按钮后,可以通过$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中为各个数组元素分配和跟踪事件?
更新
我重写了两个事件听众,取得了一些成功,但我仍然遇到奇怪的行为:
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
中的每个elemnt,使用前面提到的.uploadStatus
属性给出状态。现在我正在通过传递给自执行函数的setTimeout
变量,使i
拼接数组中的元素。奇怪的是,现在一次上传大约有6个同时上传,这一定是服务器方面的问题,但我注意到,当数组元素被拼接时,模板中的ng-repeat
表现得很奇怪它将拼接一个元素,不一定是它应该的元素。我还注意到,在达到2000毫秒的阈值后,通常会有条目没有被拼接。
这让人联想到在整个触发事件监听器时引用变量i
不可靠的原始问题?现在我将它传递给匿名自执行.onload
函数,并且splice正在使用它来确定它应该删除哪个数组元素,但它不一定要删除正确的元素,并且经常留下其他元素在数组中它应该删除它们。
答案 0 :(得分:6)
传递给事件处理程序的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'
答案 1 :(得分:4)
AngularJs 1.5.5通过为上传进度提供回调事件处理程序来改变方法。
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);
});