一种可能性是在构建时将输出从一个模块传递到另一个模块。这允许模块之间的层次关系。还有可能创建两个模块之间共享的内存,我不会在这个答案中介绍。
reactiveValues
在这里我创建了一个inputModule 和一个outputModule。 inputModule 接收用户的两个文本输入,输出模块通过verbatimTextOutput 显示它们。 inputModule 将用户提交的数据作为reactiveValues 对象传递给输出模块,称为ImProxy(输入模块代理)。 outputModule 像列表一样访问数据(ImProxy$text1、ImProxy$text2)。
library(shiny)
inputModuleUI <- function(id){
ns <- NS(id)
wellPanel(h3("Input Module"),
textInput(ns('text1'), "First text"),
textInput(ns('text2'), "Second text"))
}
inputModule <- function(input, output, session){
vals <- reactiveValues()
observe({vals$text1 <- input$text1})
observe({vals$text2 <- input$text2})
return(vals)
}
outputModuleUI <- function(id){
wellPanel(h3("Output Module"),
verbatimTextOutput(NS(id, "txt")))
}
outputModule <- function(input, output, session, ImProxy){
output$txt <- renderPrint({
paste(ImProxy$text1, "&", ImProxy$text2)
})
}
ui <- fluidPage(
inputModuleUI('IM'),
outputModuleUI('OM')
)
server <- function(input, output, session){
MyImProxy <- callModule(inputModule, 'IM')
callModule(outputModule, 'OM', MyImProxy)
}
shinyApp(ui, server)
这种方法也可以与observe 或observeEvent 一起使用。
列表(反应)
如果你想使用reactive而不是reactiveValues,可以使用上面代码的以下改编。您可以保留 ui 函数原样。
inputModule <- function(input, output, session){
list(
text1 = reactive({input$text1}),
text2 = reactive({input$text2})
)
}
outputModule <- function(input, output, session, ImProxy){
output$txt <- renderPrint({
paste(ImProxy$text1(), "&", ImProxy$text2())
})
}
shinyApp(ui, server)
反应式(列表)
同样,这将为应用提供相同的功能,但代理模式略有不同。
inputModule <- function(input, output, session){
reactive(
list(
text1 = input$text1,
text2 = input$text2
)
)
}
outputModule <- function(input, output, session, ImProxy){
output$txt <- renderPrint({
paste(ImProxy()$text1, "&", ImProxy()$text2)
})
}
shinyApp(ui, server)