Rhino框架下Shiny模块中获取表格内按钮输入的问题
解决Rhino框架Shiny模块中Reactable表格按钮无法触发输入的问题
核心问题分析
你的代码无法捕获按钮输入的原因有三个:
- 命名空间未绑定:表格模块使用了主应用的命名空间,但按钮的
Shiny.onInputChange未使用该命名空间,导致主应用无法识别输入事件。 - 重复ID冲突:所有按钮共用同一个
id="vw_item",违反HTML规范,会导致事件触发异常。 - 重复值不触发事件:Shiny默认忽略相同值的重复输入,点击同一按钮时不会重新触发
observeEvent。
分步修改方案
1. 修改逻辑模块(app/logic/fluxogramaProcesso.R)
添加命名空间参数,给按钮输入绑定模块命名空间,同时传递时间戳确保重复点击也能触发事件:
# app/logic/fluxogramaProcesso.R box::use( glue[glue], dplyr[filter, select, mutate], reactable[reactable, colDef], DBI[dbConnect, dbDisconnect, dbGetQuery], ) box::use( app/logic/connectdb, app/logic/funcTrim ) #' @export cadastroProdutos <- function(ns) { # 新增命名空间参数 con <- connectdb$create_con() produtos_query <- glue("SELECT ITEM_CODE FROM TABLE") produtos_tbl <- dbGetQuery(con, produtos_query) |> funcTrim$trimDataChar() |> as.data.frame() |> mutate( view_item = glue::glue( '<button class="btn" onclick="Shiny.onInputChange(\'{ns("vw_item")}\', {{value: \'{ITEM_CODE}\', timestamp: Date.now()}})"> <i class="fa-solid fa-eye"></i> </button>' ) # 使用模块命名空间,添加时间戳 ) |> reactable( columns = list( view_item = colDef(html = TRUE) ) ) dbDisconnect(con) return(produtos_tbl) }
2. 修改表格模块(app/view/table.R)
在模块内部传递命名空间给逻辑函数,并返回内部输入对象供主应用监听:
# app/view/table.R box::use( reactable[reactableOutput, renderReactable], shiny[moduleServer, NS, observeEvent], ) box::use( app/logic/fluxogramaProcesso # 引入逻辑模块 ) #' @export ui <- function(id) { ns <- NS(id) reactableOutput(ns("table")) } #' @export server <- function(id) { moduleServer(id, function(input, output, session){ ns <- session$ns # 获取当前模块的命名空间 output$table <- renderReactable({ fluxogramaProcesso$cadastroProdutos(ns) # 传递命名空间 }) # 返回模块内部的输入对象,供主应用监听 return(list( vw_item = reactive(input$vw_item) )) }) }
3. 修改主应用(app/main.R)
监听表格模块返回的输入事件,触发弹窗:
# app/main.R box::use( shiny[bootstrapPage, moduleServer, NS, reactive, icon, textInput, renderText, observeEvent, showModal, modalDialog], shinydashboard[dashboardPage, dashboardHeader, dashboardBody, dashboardSidebar, sidebarMenu, menuItem, tabItems, tabItem], ) box::use( app/view/table, app/view/dataTable, app/logic/dataProduct, app/logic/fluxogramaProcesso, app/logic/cadastroProdutos, ) #' @export ui <- function(id) { ns <- NS(id) dashboardPage( dashboardHeader(), dashboardSidebar( sidebarMenu( menuItem("Fluxograma de Processos", tabName = "fluxproc", icon = icon("sitemap")) ) ), dashboardBody( tabItems( tabItem(tabName = "fluxproc", table$ui(ns("cadastroProd")) ) ) ) ) } #' @export server <- function(id) { moduleServer(id, function(input, output, session) { # 调用表格模块并获取输入对象 table_inputs <- table$server("cadastroProd") # 监听按钮点击事件 observeEvent(table_inputs$vw_item(), { selected_item <- table_inputs$vw_item()$value # 获取选中的ITEM_CODE showModal( modalDialog( h2(paste("IT WORKS !!!! 选中的商品代码:", selected_item)) ) ) }) }) }
验证效果
修改完成后,点击表格内的任意按钮,会弹出包含对应商品代码的弹窗,重复点击同一按钮也能正常触发事件。
内容的提问来源于stack exchange,提问作者André Manesco
相关产品推荐
相关产品推荐

