You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny嵌套模块中conditionalPanel命名空间异常问题求助

修复嵌套模块中模态框内conditionalPanel的命名空间问题

问题场景

当子模块直接挂载到根UI时,模态框内的conditionalPanel可以正常工作:输入大于5的数字,"Show Me"文本会正常显示。但将子模块嵌套到父模块后,conditionalPanel的命名空间前缀错误,导致条件判断失效。

正常运行的一级模块代码

library(shiny)
library(bslib)

# Child module server function
childModule <- function(id, run) {
  moduleServer(id, function(input, output, session) {
    ns <- session$ns
    
    rv <- reactiveValues(
      show = FALSE
    )
    
    output$show <- reactive(input$number > 5)
    outputOptions(output, "show", suspendWhenHidden = FALSE)
    
    observeEvent(run(), {
      showModal(modalDialog(
        numericInput(ns("number"), "For Numbers >5 the conditionalPanel should show.", value = 5, min = 0, max = 100),
        
        conditionalPanel(
          condition = "output.show == true",
          ns = NS(id),
          
          "Show Me"
        ),
      ))
    })
    
  })
}

# UI
ui <- page(
  actionButton("run", "click me")
)

# Server
server <- function(input, output, session) {
  childModule("child1", reactive(input$run))
}

# Run the app
shinyApp(ui, server)

嵌套父模块后出现问题的代码

library(shiny)
library(bslib)

# Child module server function
childModule <- function(id, run) {
  moduleServer(id, function(input, output, session) {
    ns <- session$ns
    
    rv <- reactiveValues(
      show = FALSE
    )
    
    output$show <- reactive(input$number > 5)
    outputOptions(output, "show", suspendWhenHidden = FALSE)
    
    observeEvent(run(), {
      showModal(modalDialog(
        numericInput(ns("number"), "For Numbers >5 the conditionalPanel should show.", value = 5, min = 0, max = 100),
        
        conditionalPanel(
          condition = "output.show == true",
          ns = NS(id),
          
          "Show Me"
        ),
      ))
    })
    
  })
}

# Parent module UI function
parentModuleUI <- function(id) {
  ns <- NS(id)
  actionButton(ns("run"), "click me")
}

# Parent module server function
parentModule <- function(id) {
  moduleServer(id, function(input, output, session) {
    childModule("child1", reactive(input$run))
  })
}

# UI
ui <- page(
  parentModuleUI("parent1")
)

# Server
server <- function(input, output, session) {
  parentModule("parent1")
}

# Run the app
shinyApp(ui, server)

错误表现

查看HTML代码可见,conditionalPanel的命名空间前缀缺失父模块部分:

<div class="shiny-panel-conditional" data-display-if="output.show == true" data-ns-prefix="child1-" style="display: none;">Show Me</div>

正确的前缀应为parent1-child1-。

问题原因

子模块服务器中,NS(id)仅生成当前子模块的命名空间前缀,没有继承父模块的命名空间。而模块服务器中的session$ns是已经包含完整父-子层级的命名空间函数,应该用它来替代NS(id)。

修复方案

修改子模块中conditionalPanel的ns参数,将NS(id)替换为session$ns:

修复后的完整代码

library(shiny)
library(bslib)

# Child module server function
childModule <- function(id, run) {
  moduleServer(id, function(input, output, session) {
    ns <- session$ns
    
    rv <- reactiveValues(
      show = FALSE
    )
    
    output$show <- reactive(input$number > 5)
    outputOptions(output, "show", suspendWhenHidden = FALSE)
    
    observeEvent(run(), {
      showModal(modalDialog(
        numericInput(ns("number"), "For Numbers >5 the conditionalPanel should show.", value = 5, min = 0, max = 100),
        
        conditionalPanel(
          condition = "output.show == true",
          ns = session$ns,  # 替换为session$ns
          
          "Show Me"
        ),
      ))
    })
    
  })
}

# Parent module UI function
parentModuleUI <- function(id) {
  ns <- NS(id)
  actionButton(ns("run"), "click me")
}

# Parent module server function
parentModule <- function(id) {
  moduleServer(id, function(input, output, session) {
    childModule("child1", reactive(input$run))
  })
}

# UI
ui <- page(
  parentModuleUI("parent1")
)

# Server
server <- function(input, output, session) {
  parentModule("parent1")
}

# Run the app
shinyApp(ui, server)

修复后,conditionalPanel的HTML会生成正确的命名空间前缀parent1-child1-,条件判断即可正常工作。

内容的提问来源于stack exchange,提问作者eastclintw00d

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:20:22