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

如何在R Shiny模块间双向传递reactive values?

R Shiny模块间双向响应式数据传递实现

我需要一套系统可靠的R Shiny模块间双向传递响应式数据的方案作为开发模板,目前对模块间数据传递方法还不清晰。

现有示例代码的运行逻辑:

  • mod1会将基础数据框df的值乘以用户滑块输入的值
  • mod2会将mod1的计算结果全部加10
  • 目前已实现mod2表格的第一列传回mod1,并在mod1表格中新增colA_mod2列,这部分运行正常

现在需要完成的需求:将mod1中colA_mod2列的值乘以100后传回mod2,并在mod2的表格中新增名为colA_mod2_mod1的列,以此掌握模块间双向传值的核心逻辑。

修改后的完整代码

library(shiny)
library(DT)

mod1_ui <- function(id) {
  ns <- NS(id)
  DTOutput(ns("tbl"))
}

mod2_ui <- function(id) {
  ns <- NS(id)
  DTOutput(ns("tbl"))
}

mod1_server <- function(input, output, session, common) {
  new_dat <- reactive({
    df <- common$df
    svc <- common$svc()
    df * as.numeric(svc)
  })
  
  # 双向传递核心:将mod2的数据传入mod1,同时把mod1处理后的值传回mod2
  observe({
    common$mod1_dat <- new_dat()
    # 接收mod2的A列
    common$colA_mod2 <- common$mod2_table$A
    # 将colA_mod2乘100后存入共享容器,供mod2调用
    common$colA_mod2_mod1 <- common$colA_mod2 * 100
  })
  
  output$tbl <- renderDT({
    dat <- new_dat()
    # 添加从mod2传回的列
    dat$colA_mod2 <- common$colA_mod2 
    dat
  })
}

mod2_server <- function(input, output, session, common) {
  
  output$tbl <- renderDT({
    mod1_dat <- common$mod1_dat
    dat <- data.frame(mod1_dat + 10)
    # 保存mod2的表格数据供mod1调用
    common$mod2_table <- dat
    # 添加从mod1传回的处理后列
    dat$colA_mod2_mod1 <- common$colA_mod2_mod1
    dat
  })
}

ui <- fluidPage(
  mainPanel(
    h5(strong("Base table:")),
    DTOutput("table"),
    h5(strong(paste(
      "Module 1 multiplies slider input by values in above table",
      "and then tacks on column A from mod2 called `ColA_mod2´:"))),
    sliderInput("svc", "", min = 0, max = 10, value = 1),
    mod1_ui("mod1"),
    h5(strong(paste(
      "Module 2 then adds 10 to those Module 1 products [and then tacks on",
      "a new column called `ColA_mod2_mod1` which is `ColA_mod2` from mod1",
      "multipled by 100]:"))),
    mod2_ui("mod2")
  )
)

server <- function(input, output, session) {
  
  common <- reactiveValues(df = data.frame(A = 1:2, B = 3:4))
  
  output$table <- renderDT({datatable(common$df)})
  
  common$svc <- reactive(input$svc)
  
  callModule(mod1_server, "mod1", common)
  callModule(mod2_server, "mod2", common)
}

shinyApp(ui, server)

关键修改说明

  • 共享容器复用:借助reactiveValues创建的common对象作为模块间的数据桥梁,所有需要跨模块传递的响应式数据都存入其中
  • mod1端处理:在observe函数中,新增对colA_mod2的计算逻辑,将colA_mod2 * 100的结果存入common$colA_mod2_mod1,确保当colA_mod2变化时,该值自动更新
  • mod2端接收:在renderDT中取出common$colA_mod2_mod1,将其作为新列添加到mod2的表格中,实现从mod1到mod2的反向数据传递

内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 20:35:15