我试图将一段代码转换为Shiny模块,但我在lapply()中生成的renderPlot()函数似乎不起作用.我在下面创建了一个简单的例子来演示这个问题.
(注意:这里我使用的是renderText()调用,但同样的行为适用.)
app_normal.R:
library(shiny)
ui <- fixedPage(
h2("Normal example"),
uiOutput("test")
)
server <- function(input, output, session) {
output$test <- renderUI({
lapply(1:3, function(val) {
fluidRow(column(12,renderText(paste("Line", val))))
})
})
}
shinyApp(ui, server)
app_module.R:
library(shiny)
myModuleUI <- function(id) {
ns <- NS(id)
uiOutput(ns("test"))
}
myModule <- function(input, output, session) {
output$test <- renderUI({
lapply(1:3, function(val) {
fluidRow(column(12,renderText(paste("Line", val))))
})
})
}
ui <- fixedPage(
h2("Module example"),
myModuleUI("test_module")
)
server <- function(input, output, session) {
callModule(myModule, "test_module")
}
shinyApp(ui, server)
正在创建所有div元素,但它们只是无法包含绘图/文本.如何在模块内的renderUI()/ lapply()调用中正确使用Shiny renderText()或renderPlot()函数?
最佳答案 看来我在renderUI()中直接使用renderText()和renderPlot()函数的方法在正常情况下工作正常,即不在Shiny模块中操作时. Shiny会自动调用必要的textOutput()或plotOutput()来生成HTML.在Shiny模块中执行相同操作时,如何破坏此自动链接.我怀疑这是由于在分配outputIds时引入ns()调用导致输出列表中的项目分配和引用不匹配,因为在调用outputPlot()或outputText()时手动完成.
要在Shiny模块中成功使用renderUI,您需要在renderUI()中的lapply()中单独调用textOutput()和renderText():textOutput,并在observe()中的lapply()中调用renderText().这允许我们将ns()引入到textOutput()调用的outputId的生成中.
下面我已经包含了app_normal.R和app_module.R的重构,它们展示了这两个调用的解密.
app_normal_observe.R:
library(shiny)
ui <- fixedPage(
h2("Normal example"),
uiOutput("test")
)
server <- function(input, output, session) {
output$test <- renderUI({
lapply(1:3, function(val) {
fluidRow(column(12,textOutput(paste0("line_", val))))
})
})
observe({
lapply(1:3, function(val) {
output[[paste0("line_", val)]] <- renderText(paste("Line", val))
})
})
}
shinyApp(ui, server)
app_module_observe.R:
library(shiny)
myModuleUI <- function(id) {
ns <- NS(id)
uiOutput(ns("test"))
}
myModule <- function(input, output, session) {
output$test <- renderUI({
lapply(1:3, function(val) {
fluidRow(column(12,textOutput(session$ns(paste0("line_", val)))))
})
})
observe({
lapply(1:3, function(val) {
output[[paste0("line_", val)]] <- renderText(paste("Line", val))
})
})
}
ui <- fixedPage(
h2("Module example"),
myModuleUI("test_module")
)
server <- function(input, output, session) {
callModule(myModule, "test_module")
}
shinyApp(ui, server)