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

Shiny模块化后ConditionalPanel失效,如何修复?

修复Shiny模块化中ConditionalPanel失效的问题

问题原因

Shiny模块化后,所有输入输出控件的ID会自动添加模块命名空间前缀(比如你的模块ID是ww,那么plotly1控件的实际ID是ww-plotly1)。但你原来的conditionalPanel里直接用input.plotly1访问输入,JavaScript无法找到这个未带前缀的ID,导致面板无法根据勾选状态显示/隐藏。

修复方案

在conditionalPanel的条件表达式中,使用NS(id, "plotly1")生成带命名空间的正确ID,并用JavaScript的括号语法访问该输入项(因为ID包含横杠,不能用点语法)。

修正后的完整代码

library(shiny)
library(plotly)

dataset <- mtcars

mod_ui <- function(id){
  
  pageWithSidebar(
    headerPanel("Mtcars"),
    sidebarPanel(sliderInput(NS(id,'sampleSize'), 'Sample Size', min=10, max=nrow(dataset),
                             value=min(10, nrow(dataset)), step=5, round=0),
                 selectInput(NS(id, 'x'), 'X', names(dataset)),
                 selectInput(NS(id, 'y'), 'Y', names(dataset), names(dataset)[[2]]),
                 selectInput(NS(id, 'color'), 'Color', c('None', names(dataset))),
                 checkboxInput(NS(id, 'smooth'), 'Smooth'),
                 selectInput(NS(id, 'facet_row'), 'Facet Row', c(None='.', names(dataset))),
                 selectInput(NS(id,'facet_col'), 'Facet Column', c(None='.', names(dataset))),
                 hr(),
                 checkboxInput(NS(id, "plotly1"), "Interactive plot!",value = FALSE, width=140),
                 actionButton(NS(id, "plot"), "Plot!")
    ),
    mainPanel(
      plotOutput(NS(id,'plot')),
      hr(),
      hr(),
      # 修复ConditionalPanel的条件表达式
      conditionalPanel(
        condition = paste0("input['", NS(id, "plotly1"), "'] === true"),
        plotlyOutput(NS(id,"plot2"))
      )
    )
  )
  
}


mod_server <- function(id){
  moduleServer(id, function(input, output, session){
    
    dataset <- reactive( { mtcars[sample(nrow(mtcars), input$sampleSize),] } ) 
    graph <- reactive({
      p <- ggplot(dataset(), aes_string(x=input$x, y=input$y)) + geom_point()
      if (input$color != 'None')
        p <- p + aes_string(color=input$color)
      facets <- paste(input$facet_row, '~', input$facet_col)
      if (facets != '. ~ .')
        p <- p + facet_grid(facets)
      
      if (input$smooth)
        p <- p + geom_smooth()
      
      p
    }) |> bindEvent(input$plot)
    
    output$plot <- renderPlot({
      graph()
    })
    
    output$plot2 <- renderPlotly({
      ggplotly(graph())
    })
    
  })
}


simApp <- function(){
  ui <- shinyUI(
    mod_ui("ww")
  ) 
    
  server <- function(input, output, session){
    mod_server("ww")
  }
  shinyApp(ui, server)
}

simApp()

额外说明

顺便修正了代码中gragh的拼写错误为graph,不影响功能但更规范。另外,由于graph响应式对象绑定了input$plot事件,只有点击「Plot!」按钮才会更新图表数据,所以勾选「Interactive plot!」后,需要点击「Plot!」才能加载交互式图表;如果希望勾选后自动更新,可移除bindEvent(input$plot),但这样会随输入控件变化实时更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 11:03:20