Shiny应用eventReactive使用后input$param不更新问题求助
问题描述
我正在用Shiny开发一款基于用户选择输入生成报表的应用,报表通过点击“Generar reporte”按钮生成,包含三类输入:
- input_type:SelectInput,用于选择报表类型,选项为“Global”和“Por instituciones”;
- param:仅当input_type为“Por instituciones”时显示的SelectInput;
- date:用于定义报表日期的SelectInput。
异常流程
按以下操作时,param的选择不再生效,input$param始终为生成Global报表前的最后选中值:
- 选择input_type为“Global”;
- 点击“Generar reporte”生成报表;
- 切换input_type为“Por instituciones”;
- 点击“Generar reporte”生成报表。
现有代码
library(shiny) library(DT) ui <- fluidPage( sidebarLayout( sidebarPanel( titlePanel("Repotería seguimiento PEIPRDCI"), selectInput("input_type", "Tipo reporte", c("Global", "Por instituciones")), uiOutput("ui"), selectInput("date", "Seleccione la fecha:", choices = c("2023-01-01", "2023-02-01")), actionButton("generate", "Generar reporte"), downloadButton('downloadReport', "Descargar") ), mainPanel( htmlOutput("report") ) ) ) server <- function(input, output) { output$ui <- renderUI({ if (input$input_type == "Por instituciones") { selectInput("param", "Seleccione la institución:", choices = c("BDE", "DIGERCIC")) } }) a <- eventReactive(input$generate, { if(input$input_type == "Por instituciones") { print(input$param) rmarkdown::render("C:/Users/santy/Documents/test5.Rmd", params = list(institucion = input$param, fecha = input$date)) includeHTML("C:/Users/santy/Documents/test5.html") } else { print(input$param) rmarkdown::render("C:/Users/santy/Documents/Reporte_seguimiento110523.Rmd", params = list(fecha = input$date)) includeHTML("C:/Users/santy/Documents/Reporte_seguimiento110523.html") } }) output$report <- renderUI({ a() }) output$downloadReport <- downloadHandler( filename = function() { paste('my-report', sep = '.', 'html') }, content = function(file) { src <- normalizePath('C:/Users/santy/Documents/test5.Rmd') # temporarily switch to the temp dir, in case you do not have write # permission to the current working directory owd <- setwd(tempdir()) on.exit(setwd(owd)) file.copy(src, 'test5.Rmd', overwrite = TRUE) library(rmarkdown) out <- a() file.rename(out, file) } ) } shinyApp(ui = ui, server = server)
解决思路
问题根源
当切换到Global类型时,param控件被移除,Shiny不会主动清除input$param的缓存值,导致切回Por instituciones时,input$param仍保留之前的旧值,而非新选择的内容。
修复方案
方案一:强制初始化动态生成的param控件
修改renderUI中的selectInput,每次生成控件时指定默认选中项,确保重新渲染时重置值:
output$ui <- renderUI({ if (input$input_type == "Por instituciones") { selectInput("param", "Seleccione la institución:", choices = c("BDE", "DIGERCIC"), selected = "BDE") # 指定第一个选项为默认值 } })
方案二:用reactiveVal存储param的有效值
在server中创建reactiveVal跟踪param的当前有效值,避免依赖被移除的控件:
server <- function(input, output) { current_param <- reactiveVal(NULL) # 实时更新param的有效值 observe({ if (input$input_type == "Por instituciones") { current_param(input$param) } else { current_param(NULL) } }) output$ui <- renderUI({ if (input$input_type == "Por instituciones") { selectInput("param", "Seleccione la institución:", choices = c("BDE", "DIGERCIC")) } }) a <- eventReactive(input$generate, { if(input$input_type == "Por instituciones") { print(current_param()) # 使用存储的有效值 rmarkdown::render("C:/Users/santy/Documents/test5.Rmd", params = list(institucion = current_param(), fecha = input$date)) includeHTML("C:/Users/santy/Documents/test5.html") } else { rmarkdown::render("C:/Users/santy/Documents/Reporte_seguimiento110523.Rmd", params = list(fecha = input$date)) includeHTML("C:/Users/santy/Documents/Reporte_seguimiento110523.html") } }) # 其余代码保持不变... }
方案三:用conditionalPanel替代renderUI
将动态显示的param用conditionalPanel实现,控件始终存在于DOM中(仅隐藏),Shiny会持续跟踪其值:
ui <- fluidPage( sidebarLayout( sidebarPanel( titlePanel("Repotería seguimiento PEIPRDCI"), selectInput("input_type", "Tipo reporte", c("Global", "Por instituciones")), # 替换uiOutput为conditionalPanel conditionalPanel( condition = "input.input_type == 'Por instituciones'", selectInput("param", "Seleccione la institución:", choices = c("BDE", "DIGERCIC")) ), selectInput("date", "Seleccione la fecha:", choices = c("2023-01-01", "2023-02-01")), actionButton("generate", "Generar reporte"), downloadButton('downloadReport', "Descargar") ), mainPanel( htmlOutput("report") ) ) )
内容的提问来源于stack exchange,提问作者Santiago Valdivieso
相关产品推荐
相关产品推荐

