如何在Shiny渲染Rmarkdown报告时禁用downloadButton并防重复点击
解决Shiny中渲染Rmarkdown报告时重复点击下载按钮的问题
问题核心是原代码用shinyjs::onclick()只会在首次下载完成后禁用按钮,导致用户可多次触发重复渲染。正确的做法是在下载触发后立即禁用按钮,并在渲染完成(无论成功或失败)后重新启用按钮。
修改后的app.R代码如下:
library(shiny) library(shinyjs) report_path <- tempfile(fileext = ".Rmd") file.copy("report.Rmd", report_path, overwrite = TRUE) render_report <- function(input, output, params) { rmarkdown::render( input, output_file = output, params = params, envir = new.env(parent = globalenv()) ) } ui <- fluidPage( useShinyjs(), # 必须加载shinyjs sliderInput("n", "点数", 1, 100, 50), downloadButton("report", "生成报告") ) server <- function(input, output) { output$report <- downloadHandler( filename = "report.html", content = function(file) { # 触发下载时立即禁用按钮 shinyjs::disable("report") # 确保渲染完成(或出错)后重新启用按钮,add=TRUE保证不覆盖其他on.exit逻辑 on.exit(shinyjs::enable("report"), add = TRUE) params <- list(n = input$n) callr::r(render_report, list( input = report_path, output = file, params = params )) } ) } shinyApp(ui, server)
关键修改说明:
- 移除了原代码中
onclick("report", disable("report"))行:它仅在客户端点击事件触发时执行,无法精准关联下载任务的生命周期,导致按钮禁用时机滞后。 - 在
downloadHandler的content函数开头调用shinyjs::disable("report"):确保下载任务启动时立即禁用按钮,阻止重复点击。 - 使用
on.exit(shinyjs::enable("report"), add = TRUE):保证无论渲染成功完成还是抛出错误,按钮都会被重新启用,避免出现按钮永久禁用的异常情况。
report.Rmd代码无需修改,保持原内容即可。
内容的提问来源于stack exchange,提问作者retlaw
相关产品推荐
相关产品推荐

