如何实现附件逐个预览:通过当前附件的下一页按钮切换
解决方案:实现附件逐个预览+分页切换
要实现逐个打开附件并通过「下一页」按钮切换,核心是维护当前预览的附件索引,并将弹窗展示逻辑改为可复用模式,替代原有的循环批量弹窗逻辑。以下是具体修改方案:
步骤1:重构主函数,维护附件列表与当前索引
修改previsualizarTodosAdjuntos,不再循环调用预览接口,先获取所有附件ID并保存到作用域,再启动第一个附件的预览:
$scope.previsualizarTodosAdjuntos = function() { var ultimaPosicion = $scope.datos.adjuntos.preguntasAdjuntos.length - 1; var preguntasUltimaPosicion = $scope.datos.adjuntos.preguntasAdjuntos[ultimaPosicion].preguntas; // 保存所有附件ID到作用域,用于分页切换 $scope.attachmentIds = preguntasUltimaPosicion.map(pregunta => pregunta.idDetalle); // 初始化当前预览的索引 $scope.currentIndex = 0; // 打开第一个附件 $scope.openAttachmentByIndex($scope.currentIndex); };
步骤2:封装可复用的预览函数
新增根据索引预览附件的函数,整合原有的接口调用、弹窗渲染逻辑,同时支持分页切换:
// 根据索引打开单个附件 $scope.openAttachmentByIndex = function(index) { // 边界判断:索引越界则直接返回 if (index < 0 || index >= $scope.attachmentIds.length) return; var idDetalle = $scope.attachmentIds[index]; var params = { SSISTEMA: "", IEMPRESA: kUtil.empresa, IPRESUPUESTO: $scope.datos.presupuesto.presupuesto, IDETALLEPREGUNTA: idDetalle, BBASE64: true, }; ServicioNuevoPresupuesto.descargarAdjunto(params).then(function(ok) { var nameImg = ok.data.value.Rows[0].NOMBRE; var urlArchive = ok.data.value.Rows[0].DATA; var archiveBase64 = ok.data.value.Rows[0].BASE64; var allowedExtensions = ["jpg", "jpeg", "png", "gif", "pdf"]; var fileExtension = nameImg.substring(nameImg.lastIndexOf('.') + 1).toLowerCase(); if (!allowedExtensions.includes(fileExtension)) return; // 构建弹窗内容 var contentTemplate = ''; var pdfBlobUrl = null; if (fileExtension === "pdf") { // 处理PDF的Base64转Blob var byteCharacters = atob(archiveBase64); var byteNumbers = new Array(byteCharacters.length); for (var i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); } var byteArray = new Uint8Array(byteNumbers); var pdfBlob = new Blob([byteArray], { type: "application/pdf" }); pdfBlobUrl = URL.createObjectURL(pdfBlob); contentTemplate = `<iframe src="${pdfBlobUrl}" style="width: 149vh; height: 71vh;"></iframe>`; } else { contentTemplate = `<img src="${urlArchive}" alt="${nameImg}" style="max-width: 100%;">`; } // 构建带分页按钮的弹窗模板 var dialogTemplate = ` <md-dialog> <md-dialog-content> ${contentTemplate} </md-dialog-content> <md-dialog-actions> <md-button ng-click="goPrev()" ${index === 0 ? 'disabled' : ''}>上一页</md-button> <md-button ng-click="goNext()" ${index === $scope.attachmentIds.length - 1 ? 'disabled' : ''}>下一页</md-button> <md-button ng-click="closeDialog()" class="md-primary">Cerrar</md-button> </md-dialog-actions> </md-dialog> `; // 显示弹窗并绑定分页逻辑 $mdDialog.show({ template: dialogTemplate, scope: $scope.$new(), controller: function($scope, $mdDialog) { // 上一页逻辑:关闭当前弹窗,打开上一个附件 $scope.goPrev = function() { $mdDialog.hide(); $scope.$parent.openAttachmentByIndex(index - 1); }; // 下一页逻辑:关闭当前弹窗,打开下一个附件 $scope.goNext = function() { $mdDialog.hide(); $scope.$parent.openAttachmentByIndex(index + 1); }; // 关闭弹窗,清理PDF资源避免内存泄漏 $scope.closeDialog = function() { if (pdfBlobUrl) { URL.revokeObjectURL(pdfBlobUrl); } $mdDialog.hide(); }; } }); }); };
步骤3:移除冗余函数
原previsualizarTodosAdjunto和servicioPrevisualizarTodosAdjunto函数可直接删除,其逻辑已整合到openAttachmentByIndex中。
核心要点
- 索引控制:通过
$scope.currentIndex和$scope.attachmentIds跟踪预览位置,确保分页切换不越界。 - 资源清理:PDF生成的Blob URL需在弹窗关闭时释放,避免内存泄漏。
- 按钮状态:根据当前索引禁用上/下一页按钮,提升交互体验。
内容的提问来源于stack exchange,提问作者Miriam
相关产品推荐
相关产品推荐

