动态创建 tabesetPanel 时闪亮的模块命名空间问题

shiny module namespace issue with dynamic creation of tabesetPanel

我目前在使我的模块 UI 和服务器与创建布局的中间渲染UI 通信时遇到问题。这是一个有和没有动态创建 tabsetPanel 的 repex。我想问题出在名称空间,但我不知道在哪里以及如何解决它。 不工作:

mod_graphical_general_ui <- function(id){
  ns <- NS(id)
  tagList(
    selectInput(ns("myselect"), "Select a choice", choices = NULL)
)}

mod_graphical_general_server <- function(id, choices = NULL) {
  moduleServer( id, function(input, output, session){
    ns <- session$ns
    updateSelectInput(session, "myselect", choices = choices)
    
  })
}

ui <- bootstrapPage(
  uiOutput("mytabs")
)

server <- function(input, output) {
  mod_graphical_general_server("mymodule", choices = c("aaa", "bbb"))
  
  output$mytabs = renderUI({
    number_of_tabs <- 3
    names_tab <- paste0("Tab", 1:number_of_tabs)
    myTabs = lapply(1: number_of_tabs, function(x) {tabPanel(names_tab[[x]], div(uiOutput(paste0("graphics_tab", x))))})
    do.call(tabsetPanel, c(myTabs))
  })
  
  output$graphics_tab1 <- renderUI({
    return(mod_graphical_general_ui("mymodule"))
  })
}

shinyApp(ui = ui, server = server)

如果我删除调用 tabsetPanel 的步骤,代码就可以工作。

mod_graphical_general_ui <- function(id){
  ns <- NS(id)
  tagList(
    selectInput(ns("myselect"), "Select a choice", choices = NULL)
)}

mod_graphical_general_server <- function(id, choices = NULL) {
  moduleServer( id, function(input, output, session){
    ns <- session$ns
    updateSelectInput(session, "myselect", choices = choices)
    
  })
}

ui <- bootstrapPage(
  #uiOutput("mytabs")
  uiOutput("graphics_tab1")
)

server <- function(input, output) {
  mod_graphical_general_server("mymodule", choices = c("aaa", "bbb"))
  
  output$mytabs = renderUI({
    number_of_tabs <- 3
    names_tab <- paste0("Tab", 1:number_of_tabs)
    myTabs = lapply(1: number_of_tabs, function(x) {tabPanel(names_tab[[x]], div(uiOutput(paste0("graphics_tab", x))))})
    do.call(tabsetPanel, c(myTabs))
  })
  
  output$graphics_tab1 <- renderUI({
    return(mod_graphical_general_ui("mymodule"))
  })
}

shinyApp(ui = ui, server = server)

我已经在社区 rstudio 中问过这个问题,但没有成功。

无论如何,我已经修复了你的代码。

事情是你的 mod 服务器是 运行 作为顶级闪亮服务器启动。但是,您的 mod UI 晚于 mod 服务器 运行ning。所以这导致 updateSelectInput 找不到要更新的动态 UI 组件。在您的第二个示例中,UI 组件在应用程序启动时已经存在,因此不会出现此问题。

我们需要等待渲染 UI 事件完成后才能调用 mod 服务器。要理解这一点,你需要了解 Shiny 是如何与前端通信的 javascript,这里不再赘述。您可以在 this issue.

上阅读更多内容
mod_graphical_general_ui <- function(id){
  ns <- NS(id)
  tagList(
    selectInput(ns("myselect"), "Select a choice", choices = NULL)
  )}

mod_graphical_general_server <- function(id, choices = NULL) {
  moduleServer(id, function(input, output, session){
    ns <- session$ns
    updateSelectInput(session, "myselect", choices = choices)
    
  })
}

ui <- bootstrapPage(
  uiOutput("mytabs")
)

server <- function(input, output, session) {
  output$mytabs = renderUI({
    number_of_tabs <- 3
    names_tab <- paste0("Tab", 1:number_of_tabs)
    myTabs = lapply(1:number_of_tabs, function(x) {tabPanel(names_tab[[x]], div(uiOutput(paste0("graphics_tab", x))))})
    do.call(tabsetPanel, c(myTabs))
  })
  
  output$graphics_tab1 <- renderUI({
    on.exit({
      observeEvent(once = TRUE, reactiveValuesToList(session$input), {
        mod_graphical_general_server("mymodule", choices = c("aaa", "bbb"))
      }, ignoreInit = TRUE)
    })
    return(mod_graphical_general_ui("mymodule"))
  })
}

shinyApp(ui = ui, server = server)