在Shiny模块中点击reactable行触发模态框失效问题
Shiny模块中reactable行点击触发模态框失效的解决方案
问题根源
Shiny模块会自动给内部所有输入、输出和UI元素加上命名空间前缀,非模块环境下写的JS代码直接用原始ID调用,到了模块里就找不到对应的元素或输入,自然触发不了模态框。
关键修复点
- 模块里所有UI元素的ID必须用
NS()/session$ns()包裹,包括模态框的ID - reactable的点击事件JS代码里,要把命名空间前缀注入到输入ID和模态框选择器中
- 关闭模态框的逻辑也要对应加上命名空间前缀
代码示例
非模块正常版本(参考)
library(shiny) library(reactable) ui <- fluidPage( reactableOutput("table"), modalDialog( textOutput("row_data"), id = "modal", footer = actionButton("close_modal", "关闭") ) ) server <- function(input, output, session) { output$table <- renderReactable({ reactable( mtcars, onClick = JS("function(rowInfo) { Shiny.setInputValue('row_click', rowInfo.index); $('#modal').modal('show'); }") ) }) output$row_data <- renderText({ req(input$row_click) paste("你点击了第", input$row_click + 1, "行,数据:", toString(mtcars[input$row_click + 1, ])) }) observeEvent(input$close_modal, { $('#modal').modal('hide') }) } shinyApp(ui, server)
修复后的模块版本
library(shiny) library(reactable) # 模块UI tableModalUI <- function(id) { ns <- NS(id) tagList( reactableOutput(ns("table")), modalDialog( textOutput(ns("row_data")), id = ns("modal"), # 给模态框ID加命名空间 footer = actionButton(ns("close_modal"), "关闭") ) ) } # 模块Server tableModalServer <- function(id) { moduleServer(id, function(input, output, session) { ns <- session$ns output$table <- renderReactable({ reactable( mtcars, # 用sprintf把命名空间注入到JS代码里 onClick = JS(sprintf("function(rowInfo) { Shiny.setInputValue('%s', rowInfo.index); $('#%s').modal('show'); }", ns("row_click"), ns("modal"))) ) }) output$row_data <- renderText({ req(input$row_click) paste("你点击了第", input$row_click + 1, "行,数据:", toString(mtcars[input$row_click + 1, ])) }) observeEvent(input$close_modal, { # 关闭模态框也要用带命名空间的选择器 $(paste0("#", ns("modal"))).modal('hide') }) }) } # 主应用 ui <- fluidPage( tableModalUI("test_module") ) server <- function(input, output, session) { tableModalServer("test_module") } shinyApp(ui, server)
说明
核心就是让JS代码里的ID和模块内实际生成的ID完全匹配——模块会把你定义的ID加上类似test_module-的前缀,所以必须通过ns()方法把前缀注入到JS里,不然JS找不到对应的模态框和输入项。
内容的提问来源于stack exchange,提问作者Antônio
相关产品推荐
相关产品推荐

