为何Shiny动态UI结合模块化开发无法得到预期输出?
问题原因
你的推测方向正确,问题根源就是模块内动态UI的ID没有匹配模块命名空间:
在Shiny模块的服务端逻辑中,所有自行动态生成的*Output类元素的ID,都需要通过当前模块的session$ns()方法添加模块专属命名空间,才能和服务端output[[id]]的命名规则对应上。你之前的代码中动态生成DT::dataTableOutput(id)时直接使用了原始ID,没有加命名空间,导致前端找不到对应的服务端渲染结果,因此显示为空。
注意:模块服务端内的output[[id]]不需要额外添加命名空间,moduleServer已经自动给output对象封装了模块命名空间,直接使用原始ID即可。
修复后的可运行代码
仅需要修改tab_server函数内renderUI部分的代码即可,完整代码如下:
## library library(shiny) library(shinydashboard) library(datasets) library(dplyr) library(DT) ## data cars <- mtcars irises <- iris cars$team <- sample(c("Team1", "Team2"), nrow(cars), replace = TRUE) irises$team <- sample(c("Team1", "Team2"), nrow(irises), replace = TRUE) ## module UI tab_ui <- function(id) { uiOutput(NS(id, "content")) } ## module Server tab_server <- function(id, data, Team, var) { moduleServer(id, function(input, output, session) { table <- reactive({ data %>% filter(team == Team) }) output$content <- renderUI({ lapply(sort(unique(table()[[var]])), function(i) { id <- paste0("content_", i) output[[id]] <- DT::renderDataTable(datatable(table()[table()[[var]] == i, ])) fluidRow( box( width = "100%", title = paste0(var, " ", i), status = "info", solidHeader = TRUE, collapsible = TRUE, # 仅修改了这一行:给output ID套上session$ns DT::dataTableOutput(session$ns(id)) ) ) }) }) }) } ## UI ui <- dashboardPage( dashboardHeader(title = "Teams"), dashboardSidebar(sidebarMenu( menuItem("Team 1", tabName = "tab_team1" ), menuItem("Team 2", tabName = "tab_team2" ) )), dashboardBody(tabItems( tabItem( tabName = "tab_team1", fluidRow( tabBox( title = "", width = "100%", tabPanel( title = "A", tab_ui("team1_tabA") ), # module ui tabPanel( title = "B", tab_ui("team1_tabB") ) # module ui ) ) ), tabItem( tabName = "tab_team2", fluidRow( tabBox( title = "", width = "100%", tabPanel( title = "A", tab_ui("team2_tabA") ), # module ui tabPanel( title = "B", tab_ui("team2_tabB") ) # module ui ) ) ) )) ) ## server server <- function(input, output, session) { # module server tab_server("team1_tabA", data = cars, Team = "Team1", var = "gear") tab_server("team1_tabB", data = irises, Team = "Team1", var = "Species") tab_server("team2_tabA", data = cars, Team = "Team2", var = "gear") tab_server("team2_tabB", data = irises, Team = "Team2", var = "Species") } shinyApp(ui, server)
内容的提问来源于stack exchange,提问作者Xiang
相关产品推荐
相关产品推荐

