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

Shiny技术问题:仅点击Action Button后显示Download Button

Shiny中实现点击按钮后显示下载按钮的解决方案

原代码中控制下载按钮显示的逻辑未生效,核心原因是actionButton的input$bttn1初始值为0,而非NULL,所以用is.null(input$bttn1)的判断条件永远不成立,导致下载按钮始终显示。

下面提供两种简洁的解决方案:

方案一:修正判断逻辑并初始隐藏按钮

直接基于input$bttn1的数值判断是否点击过按钮(初始为0,点击后递增),同时在应用启动时先隐藏下载按钮:

## downloadButton
output$ui_download <- renderUI({
  downloadButton("download", "Download")
})

# 控制按钮显示隐藏的逻辑
observe({
  if (input$bttn1 == 0) { # 未点击过Add按钮时
    shinyjs::hide("download")
  } else {
    shinyjs::show("download")
  }
})

# 初始启动时隐藏按钮,设置高优先级确保先执行
observe({
  shinyjs::hide("download")
}, priority = 10)

方案二:用req()控制按钮渲染(更推荐)

利用Shiny的req()函数,只有当点击Add按钮后生成的rv1$values存在时,才渲染下载按钮。这种方式无需额外控制显示隐藏,更符合响应式编程逻辑:

## downloadButton - 仅当rv1$values存在时渲染按钮
output$ui_download <- renderUI({
  req(rv1$values)
  downloadButton("download", "Download")
})

完整修正后的代码(方案二版本)

##### ui
ui <- dashboardPage(
  skin = "black",
  
  #### Upper navigation bar
  dashboardHeader(
    title = "title",
    titleWidth = 230
  ),
  
  
  #### Side bar
  dashboardSidebar(disable = T),
  
  
  #### Body
  dashboardBody(
    shinyjs::useShinyjs(),
    
    tabsetPanel(
      tabPanel(
        
        ### tab1
        tabName = "tab1", 
        h5("Tab 1"),
        
        fluidRow(
          
          reactableOutput("table1"),
          
          textInput("textinput1", "Initials:"),
          actionButton("bttn1", "Add", class = "btn-primary"),
          
          reactableOutput("table2"),
          uiOutput("ui_download")
          
        ) # fluidRow
      ), # tabPanel
      
      
      #### tab2
      tabPanel(
        tabName = "tab2", 
        h5("Tab 2"),
        
        fluidRow(
          
        ) # fluidRow
      ) # tabPanel
    ) # tabsetPanel
    
    
  ) # dashboardBody
) # dashboardPage


#### server 
server <- function(input, output, session) {
  
  ## df1
  # reactive
  df1 <- reactive({
    data.frame(
      "id" = c("A", "A", "A", "A"),
      "num1" = c(10, 11, 12, 13)
    )
  })
  
  # renderReactable
  output$table1 <- renderReactable({
    reactable(df1(), borderless = F, defaultColDef = colDef(align = "center"))
  })
  
  ## df2
  ## Text input 
  rv1 <- reactiveValues()
  
  observe({
    if (nrow(df1()) == 0) {shinyjs::hide("bttn1")} 
    else {shinyjs::show("bttn1")}
  })
  
  observe({
    if (nrow(df1()) == 0) {shinyjs::hide("textinput1")} 
    else {shinyjs::show("textinput1")}
  })
  
  observeEvent(input$bttn1, {
    rv1$values <- df1()
    rv1$values$name <- input$textinput1
  })
  
  rv1_text <- reactive({
    rv1$values
  })
  
  output$table2 <- renderReactable({
    req(rv1_text())
    reactable(rv1_text(), borderless = F, defaultColDef = colDef(align = "center"))
  })
  
  ## downloadButton
  # renderUI - 仅当rv1$values存在时渲染按钮
  output$ui_download <- renderUI({
    req(rv1$values)
    downloadButton("download", "Download")
  })
  
  # Download csv
  output$download <- downloadHandler(
    filename = function() {
      paste0('data', '.csv')
    },
    
    content = function(file) {
      write.csv(rv1_text(), file, row.names = F)
    }
  )
  
}

shinyApp(ui, server)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 03:21:03