Shiny模态对话框中Radio Buttons无法选中值的问题及方案求助
问题原因
你的代码核心问题是将模态框弹出逻辑写在了renderPrint()响应式表达式内部:当你点击单选按钮修改input$chooseGeog时,会触发renderPrint()重新执行,导致showModal()被反复调用,模态框不断重载,选中值自然无法保留。
a) 修复方案
只需要拆分响应式逻辑,将查询触发、模态框控制、结果存储三个环节拆开即可:
- 用
reactiveVal()存储最终选中的CSD结果 - 用
observeEvent()监听「Find Me!」按钮点击,执行邮编匹配,多结果时弹出模态框 - 用
observeEvent()监听模态框的OK按钮点击,将选中的CSD存入响应式变量后关闭模态框 - 输出逻辑只依赖存储结果的响应式变量,不会触发模态框重复弹出
修复后完整代码
library(shiny) library(shinycssloaders) library(dplyr) ui <- fluidPage( sidebarLayout( sidebarPanel( splitLayout( textInput("pcode", NULL, value="", placeholder = "e.g., A1A1A1"), actionButton("findpc", "Find Me!")) ), mainPanel( withSpinner(verbatimTextOutput("mygeog")) ) ) ) server <- function(input, output, session) { load(file("https://quantoid.net/files/so/pccf_reprex.rda")) # 响应式变量存储最终选中的CSD selected_csd <- reactiveVal(NULL) # 监听查询按钮点击 observeEvent(input$findpc, { mypc <- gsub(" ", "", input$pcode) tmp_pc <- filter(pccf_reprex, PC == mypc) if(nrow(tmp_pc) == 1){ # 唯一结果直接赋值 selected_csd(tmp_pc$CSDname[1]) } else if(nrow(tmp_pc) > 1){ # 多结果弹出模态框 geog_chc <- setNames(tmp_pc$CSDuid, tmp_pc$CSDname) showModal(dedupModal(chc = geog_chc)) # 存当前匹配的临时结果,避免后续重复查询 session$userData$tmp_pc <- tmp_pc } else { selected_csd("未匹配到对应邮编的普查分区") } }) # 模态框定义 dedupModal <- function(chc) { modalDialog( span('Your Post Code did not identify a unique CSD. Please pick the appropriate one from the list below.'), radioButtons("chooseGeog", "Choose Region", choices = chc, selected=character(0)), footer = tagList( actionButton("ok", "OK") ) ) } # 监听模态框OK按钮 observeEvent(input$ok, { req(input$chooseGeog) # 从临时存储取匹配结果,按选中值过滤 tmp_pc <- filter(session$userData$tmp_pc, CSDuid == input$chooseGeog) selected_csd(tmp_pc$CSDname[1]) removeModal() }) # 输出仅依赖selected_csd output$mygeog <- renderPrint({ req(selected_csd()) paste0("Geographic Indicator CSD: ", selected_csd()) }) } shinyApp(ui, server)
b) 更优实现方案
如果需要进一步优化,可以参考以下方向:
- 增加邮编格式校验,查询前先判断用户输入是否符合加拿大邮编的正则规则,减少无效查询
- 若多匹配场景占比较高,可以把选择逻辑放到侧边栏而非模态框,减少用户操作步骤
- 增加重置按钮,支持用户清空当前选择重新查询
内容的提问来源于stack exchange,提问作者DaveArmstrong
相关产品推荐
相关产品推荐

