Code
这可以很容易地解决modules https://shiny.rstudio.com/articles/modules.html:
library(shiny)
row_ui <- function(id) {
ns <- NS(id)
fluidRow(
column(3,
selectInput(ns("type_chooser"),
label = "Choose Type:",
choices = c("text", "numeric"))
),
column(9,
uiOutput(ns("ui_placeholder"))
)
)
}
row_server <- function(input, output, session) {
return_value <- reactive({input$inner_element})
ns <- session$ns
output$ui_placeholder <- renderUI({
type <- req(input$type_chooser)
if(type == "text") {
textInput(ns("inner_element"), "Text:")
} else if (type == "numeric") {
numericInput(ns("inner_element"), "Value:", 0)
}
})
## if we later want to do some more sophisticated logic
## we can add reactives to this list
list(return_value = return_value)
}
ui <- fluidPage(
div(id="placeholder"),
actionButton("addLine", "Add Line"),
verbatimTextOutput("out")
)
server <- function(input, output, session) {
handler <- reactiveVal(list())
observeEvent(input$addLine, {
new_id <- paste("row", input$addLine, sep = "_")
insertUI(
selector = "#placeholder",
where = "beforeBegin",
ui = row_ui(new_id)
)
handler_list <- isolate(handler())
new_handler <- callModule(row_server, new_id)
handler_list <- c(handler_list, new_handler)
names(handler_list)[length(handler_list)] <- new_id
handler(handler_list)
})
output$out <- renderPrint({
lapply(handler(), function(handle) {
handle()
})
})
}
shinyApp(ui, server)
解释
模块是一段模块化的代码,您可以根据需要多次重用它,而不必担心唯一的名称,因为模块在namespaces
.
一个模块由 2 部分组成:
- A
UI
功能
- A
server
功能
它们与正常人非常相似UI
and server
函数,需要记住一些事项:
-
namespacing
:在服务器内,您可以访问来自UI
就像你通常做的那样,例如input$type_chooser
。然而,在UI
部分,你必须namespace
你的元素,通过使用NS
,它返回一个函数,您可以在代码的其余部分方便地使用该函数。为此UI
函数接受一个参数id
它可以被视为该模块的任何实例的(唯一)命名空间。元素ids
在模块内必须是唯一的,并且由于命名空间,它们在整个应用程序中也将是唯一的,即使您使用模块的多个实例。
-
UI
: 身为你的UI
是一个函数,它只有one返回值,您必须将元素包装在tagList
如果你想返回多个元素(这里不需要)。
-
server
: 你需要session
参数,否则是可选的。如果您希望模块与主应用程序进行通信,则可以传入一个(反应性)参数,您可以像往常一样在模块中使用该参数。同样,如果您希望主应用程序使用模块中的某些值,您应该返回反应,如代码中所示。如果你想创造UI
服务器函数中的元素,您还需要对它们进行命名空间,并且可以通过以下方式访问命名空间函数session$ns
如图所示。
-
usage
:要使用您的模块,请插入UI
通过使用唯一的调用函数来将其作为主应用程序的一部分id
。然后你必须打电话callModule
为了使服务器逻辑正常工作,您可以在其中传递相同的内容id
。该调用的返回值是returnValue
模块服务器功能的一部分,并且可以在主应用程序中使用模块内的值。
简而言之,这解释了模块。可以找到一个非常好的教程,它更详细和完整地解释了模块here. https://shiny.rstudio.com/articles/modules.html