You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rhino框架下Shiny模块中获取表格内按钮输入的问题

解决Rhino框架Shiny模块中Reactable表格按钮无法触发输入的问题

核心问题分析

你的代码无法捕获按钮输入的原因有三个:

  1. 命名空间未绑定:表格模块使用了主应用的命名空间,但按钮的Shiny.onInputChange未使用该命名空间,导致主应用无法识别输入事件。
  2. 重复ID冲突:所有按钮共用同一个id="vw_item",违反HTML规范,会导致事件触发异常。
  3. 重复值不触发事件: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:07:02