tutorial ejemplos descargar javascript angularjs

javascript - ejemplos - AngularJS: estado de seguimiento de cada archivo que se carga simultáneamente



angularjs tutorial (2)

AngularJs 1.5.5 cambia el enfoque proporcionando controladores de eventos de devolución de llamada para el progreso de la carga.

Referencia - ¿Cómo rastrear el progreso usando eventHandlers y uploadEventHandlers en angularjs 1.5.5 con $ http o $ resource?

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); });

Al presionar un botón de enviar, una matriz de archivos ( $scope.files , puede ser tan poco como un archivo, tantos como el usuario desee) se envía a través de FormData y XMLHttpRequest en mi función angular $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); } }

El problema es que var i incrementa en el bucle for for inicial para cada archivo, y para cuando los detectores de eventos se disparan, ya he aumentado el valor de files[i] pretendidos files[i] necesarios, solo afectando al último en la matriz. Utilizo .uploadStatus como un medio para mostrar interactivamente el progreso de cada archivo individual al usuario, por lo que necesitaría tener oyentes de eventos separados para cada elemento de la matriz en $scope.files . ¿Cómo puedo asignar y rastrear eventos para elementos de matriz individuales en Angular?

ACTUALIZAR

Repasé a los dos oyentes del evento, con un poco de éxito, pero todavía estoy experimentando un comportamiento extraño:

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 parece .onprogress sin problemas, pero con algunos pequeños cambios realizados en .onload , ahora estoy viendo un comportamiento extraño con el enlace bidireccional de AngularJS para sus plantillas. para cada elemnt en array $scope.files se da un estado, usando la propiedad .uploadStatus antes mencionada. Ahora estoy haciendo que setTimeout empalme los elementos de la matriz, a través de la variable i que se transfiere a la función autoejecutable. Por extraño que parezca, las cargas están limitando a alrededor de 6 cargas simultáneas por vez, eso debe ser un problema del lado del servidor, pero me doy cuenta de que a medida que los elementos de la matriz se empalman, la ng-repeat en la plantilla actúa extrañamente donde empalme un elemento, no necesariamente los que debería. También he notado que a menudo hay entradas que no se empalman después de que se alcanza el umbral de 2000 milisegundos.

Esto es una reminiscencia del problema original donde la variable i no es confiable cuando se hace referencia a lo largo de la activación de los oyentes del evento. Ahora lo .onload función anónima autoejecutable .onload , y el empalme lo usa para determinar qué elemento de matriz debe eliminarse, pero no necesariamente elimina el correcto y, a menudo, deja otros elementos en el conjunto. cuando debería eliminarlos.


El index que pasa a los manejadores de eventos se refiere a los índices en la matriz original. Después de cada llamada exitosa para splice , la matriz cambia y los índices ya no apuntan a la misma cosa.

$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''