R Shiny模块通信问题:如何在另一模块获取selectInput的值
问题解决:Shiny跨模块获取输入值
你的问题核心是Shiny模块的命名空间隔离,不同模块的input/output不能直接跨模块访问。要让按钮模块获取selectInput的选中值,需要通过模块间的reactive传递实现,具体修改步骤如下:
1. 修改selectInput模块的Server逻辑,返回选中值
让updateServer返回一个reactive对象,对外暴露选中的活动选项:
updateServer <- function(id, my_x){ moduleServer(id, function(input, output, session){ # 更新selectInput选项 act.opts <- unique(my_x) updateSelectInput(session, "act", choices = c("All", act.opts), selected = "All") # 返回选中值的reactive对象 return(reactive({ if(input$act == "All"){ act.opts # 如果选All,返回所有活动 } else { input$act } })) }) }
2. 修改按钮模块的Server,接收外部传递的reactive值
让actionButtonServer接收一个参数,就是select模块传递过来的选中值:
actionButtonServer <- function(id, selected_acts){ moduleServer(id, function(input, output, session){ observeEvent(input$PLOT, { print("Button Check") # 直接使用传递过来的reactive值 act <- selected_acts() print(act) }) }) }
3. 主Server中完成模块间的参数传递
在主server里,先接收select模块返回的reactive对象,再传递给按钮模块:
server <- function(input, output) { # 接收select模块返回的选中值 selected_activities <- updateServer('act_1', df_use$Activity) # 把选中值传递给按钮模块 actionButtonServer('button1', selected_activities) }
完整修改后的代码
# 读取数据并创建事件日志 data <- read.csv2(file = "Data/FX_test.csv", stringsAsFactors = FALSE, na.strings=c("")) df_use <- data df_use$Timestamp = as.POSIXct(df_use$Timestamp, format = "%Y-%m-%d %H:%M:%S") # Create Event Log events <- bupaR::activities_to_eventlog( df_use, case_id = 'Case.ID', activity_id = 'Activity', resource_id = 'User', timestamp = c('Timestamp', 'Timestamp') ) # selectInput UI模块 updateUI <- function(id, list_act){ ns <- NS(id) selectInput(ns("act"), h5(strong(em("ACTIVITIES"))), choices = NULL, multiple = TRUE) } # selectInput Server模块(修改后返回选中值) updateServer <- function(id, my_x){ moduleServer(id, function(input, output, session){ act.opts <- unique(my_x) updateSelectInput(session, "act", choices = c("All", act.opts), selected = "All") return(reactive({ if(input$act == "All"){ act.opts } else { input$act } })) }) } # 按钮UI模块 actionButtonUI <- function(id){ ns <- NS(id) actionButton(ns("PLOT"), label = "PLOT", style = "color: #fff; background-color: #337ab7;border-color: #2e6da4") } # 按钮Server模块(修改后接收外部reactive值) actionButtonServer <- function(id, selected_acts){ moduleServer(id, function(input, output, session){ observeEvent(input$PLOT, { print("Button Check") act <- selected_acts() print(act) }) }) } # 主UI ui <- fluidPage( updateUI('act_1'), actionButtonUI('button1') ) # 主Server(修改后完成模块间传递) server <- function(input, output) { selected_activities <- updateServer('act_1', df_use$Activity) actionButtonServer('button1', selected_activities) } shinyApp(ui = ui, server = server)
关键说明
- Shiny模块的命名空间是隔离的,每个模块只能访问自己内部的
input/output,跨模块访问必须通过传递reactive对象实现 - 让数据产生的模块(selectInput)返回reactive值,数据使用的模块(按钮)接收这个值,是Shiny模块通信的标准方式
内容的提问来源于stack exchange,提问作者PierreMa
相关产品推荐
相关产品推荐

