You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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)

关键修改说明:

  1. 移除了原代码中onclick("report", disable("report"))行:它仅在客户端点击事件触发时执行,无法精准关联下载任务的生命周期,导致按钮禁用时机滞后。
  2. 在downloadHandler的content函数开头调用shinyjs::disable("report"):确保下载任务启动时立即禁用按钮,阻止重复点击。
  3. 使用on.exit(shinyjs::enable("report"), add = TRUE):保证无论渲染成功完成还是抛出错误,按钮都会被重新启用,避免出现按钮永久禁用的异常情况。

report.Rmd代码无需修改,保持原内容即可。

内容的提问来源于stack exchange,提问作者retlaw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:55:18