在一个闪亮的应用程序中,我有 2 个模块,在第一个模块 (mod_1_ui) 中,我有过滤器和一个 actionButton。
在模块 2 上,我想显示一个情节WHEN按钮被点击。
我的问题是,observeEvent 在模块 2 中,按钮在模块 1 中。
我如何在 2 个不同的模块中观察一个动作?
下面是一个可重现的例子:
mod_1_ui = function(id) {
ns = NS(id)
fluidRow(
column(
width = 3,
radioButtons(
ns("dist"),
"Distribution type:",
c(
"Normal" = "norm",
"Uniform" = "unif",
"Log-normal" = "lnorm",
"Exponential" = "exp"
)
),
actionButton(
inputId = ns("btn_go"),
label = "Go !",
icon = icon("play")
)
),
column(width = 9,
mod_2_ui(ns("display_plot"))
)
)
}
mod_1_server = function(id, r_global) {
moduleServer(id, function(input, output, session) {
mod_2_server("display_plot")
})
}
mod_2_ui = function(id) {
ns = NS(id)
plotOutput(outputId = ns("plot"))
}
mod_2_server = function(id, r_global) {
moduleServer(id, function(input, output, session) {
observeEvent(input$btn_go,{
output$plot <- renderPlot({
plot(mtcars$mpg)
})
})
})
}
ui <- fluidPage(
mod_1_ui("mod")
)
server <- function(input, output, session) {
r_global <- reactiveValues()
mod_1_server("mod", r_global = r_global)
}
if (interactive())
shinyApp(ui, server)
一个选项是使用
reactive
或 reactiveVal
将按钮的状态作为参数传递给模块 2 服务器:
library(shiny)
mod_1_ui <- function(id) {
ns <- NS(id)
fluidRow(
column(
width = 3,
radioButtons(
ns("dist"),
"Distribution type:",
c(
"Normal" = "norm",
"Uniform" = "unif",
"Log-normal" = "lnorm",
"Exponential" = "exp"
)
),
actionButton(
inputId = ns("btn_go"),
label = "Go !",
icon = icon("play")
)
),
column(
width = 9,
mod_2_ui(ns("display_plot"))
)
)
}
mod_1_server <- function(id, r_global) {
moduleServer(id, function(input, output, session) {
show <- reactive({
input$btn_go
})
mod_2_server("display_plot", show = show)
})
}
mod_2_ui <- function(id) {
ns <- NS(id)
plotOutput(outputId = ns("plot"))
}
mod_2_server = function(id, r_global, show) {
moduleServer(id, function(input, output, session) {
observeEvent(show(),{
output$plot <- renderPlot({
plot(runif(10, runif(10)))
})
})
})
}
ui <- fluidPage(
mod_1_ui("mod")
)
server <- function(input, output, session) {
r_global <- reactiveValues()
mod_1_server("mod", r_global = r_global)
}
if (interactive()) {
shinyApp(ui, server)
}