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

如何将动作按钮及响应式输入传入R Shiny模块服务器段?

Shiny模块改造实现方案

直接看改造后的完整可运行代码:

library(rhandsontable)
library(shiny)

seriesGenTrm <- data.frame('Series_1' = c(1), row.names = c("Input_1"))

calc <- function(x) {
  x <- max(x, 1)
  Sys.sleep(x)
  result <- x * 2
  result <- data.frame(c(x, result))
  result
}

# 定义UI模块
mod1_ui <- function(id) {
  ns <- NS(id)
  tagList(
    actionButton(ns("addSeries"), "Add series"),
    actionButton(ns("calculate"), "Calculate"),
    tableOutput(ns("alloc_tbl"))
  )
}

# 定义服务器模块
mod1_server <- function(id, seriesTbl_1) {
  moduleServer(id, function(input, output, session) {
    # 原START到END的代码移至此处
    observeEvent(input$addSeries, {
      newSeriesCol_1 <- data.frame(c(1))
      # 直接使用同步后的反应式值获取列数,无需重复读取表格输入
      names(newSeriesCol_1) <- paste0("Series_", ncol(seriesTbl_1()) + 1)
      seriesTbl_1(cbind(seriesTbl_1(), newSeriesCol_1))
    })
    
    addCol <- function(allocData, columnName, seriesTbl_1) {
      allocData[[columnName]] <- 
        calc(seriesTbl_1()[1, colnames(seriesTbl_1()) == columnName])
      return(allocData)
    }
    
    allocData <- reactiveVal(data.frame(Row = 1:2, Input_1 = c(1, 2)))
    
    observeEvent(input$calculate, {
      allocDataTmp <- data.frame(Row = 1:2)
      for (colName in colnames(seriesTbl_1())) {
        allocDataTmp <- addCol(allocDataTmp, colName, seriesTbl_1)
      }
      allocData(allocDataTmp)
    })
    
    output$alloc_tbl <- renderTable({allocData()})
  })
}

ui <- fluidPage(
  rHandsontableOutput('hottable_1'), br(),
  # 调用模块UI
  mod1_ui("mod1")
)

server <- function(input, output, session) {
  seriesTbl_1 <- reactiveVal(seriesGenTrm)
  
  observeEvent(input$hottable_1, {
    seriesTbl_1(hot_to_r(input$hottable_1))
  })
  
  output$hottable_1 <- renderRHandsontable({
    rhandsontable(
      data.frame(seriesTbl_1(), check.names = FALSE),
      rowHeaderWidth = 100
    )
  })
  
  # 调用模块服务器,传入共享的反应式值
  mod1_server("mod1", seriesTbl_1)
}

shinyApp(ui, server)

关键改造说明

  • UI模块命名空间:通过NS(id)创建命名空间,模块内所有控件ID用ns()包裹,避免和主程序ID冲突。
  • 反应式值传递:将主程序中的seriesTbl_1作为参数传入模块服务器,模块可直接读取和修改该值,实现数据同步。
  • 按钮事件处理:模块内的按钮自动继承命名空间,无需额外配置,直接通过input$addSeries/input$calculate监听触发事件。
  • 代码优化:移除原代码中重复读取input$hottable_1的逻辑,直接使用已同步的seriesTbl_1(),提升运行效率。

内容的提问来源于stack exchange,提问作者Village.Idyot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 18:33:12