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
相关产品推荐
相关产品推荐

