R Shiny Dashboard 在初始化时不会在 sidebarMenu 内部加载渲染 UI

R Shiny Dashboard does not load rendered UI inside of sidebarMenu on initialization

我正在尝试生成一个 UI 元素,它是基于用户希望如何提供输入的动态元素。为简单起见,我正在使用 Shiny Dashboard,但我遇到了 sidebarMenu 的问题。以前,当我将静态 UI 元素直接放入 sidebarMenu 时,我没有遇到任何问题,但是当我尝试将动态 UI 元素放入 sidebarMenu 时,我遇到了问题。我正在使用 R 3.3.2、Shiny 1.0.0 和 Dashboard 0.5.3。

我遇到的具体问题是,当程序首次加载时,动态 UI 元素不会加载。代码中似乎没有任何阻碍,因为即使动态 UI 已卸载,界面的所有功能也能正常工作。我可以通过选择导航栏中的一个选项卡或将鼠标悬停在我已实现工具提示的内容上来加载动态 UI。

我无法提供确切的代码,但我重新创建了一个更小的可重现示例,它与我的较大版本存在的所有问题都相同。

library("shiny")
library("shinydashboard")

header = dashboardHeader(
    title = "Dynamic UI Example"
)
sidebar = dashboardSidebar(
    sidebarMenu(
        menuItemOutput("dynamic_sidebar")
    )
)
body = dashboardBody(
    tabBox(
        tabPanel(
            strong("One")
        ),
        tabPanel(
            strong("Two")
        )
    )
)
ui = dashboardPage(header, sidebar, body)

server = shinyServer(function(input,output,session){
output$dynamic_sidebar = renderMenu({
        sidebarMenu(
            menuItem(
                "Slider or numeric problem",
                radioButtons("slider_or_numeric",
                   label = "Slider or Numeric Input",
                   choices = c("Slider", "Numeric"),
                   selected = "Slider",
                   inline = TRUE
                ),
                uiOutput("input")
            )     
        )
    })
    output$input = renderUI({
        if (input$slider_or_numeric == "Slider"){
            sliderInput("slider", 
                label = "slider",
                min = 0, max = 1,
                value = 0
            )
        } else {
            numericInput("numeric", 
                label = "numeric",
                min = 0, max = 1,
                value = 0
            )
        }
    })
})

shinyApp(ui, server)

要验证问题,加载后只需打开菜单项,您将看到单选按钮,但没有其他内容。将导航栏上的选项卡从一个切换到两个,输入应该出现在菜单中(必须在菜单打开时完成)。

我真的只是在这里抓住救命稻草,我已经对此进行了数小时的故障排除,我认为这只是与这些功能不兼容。我真的希望有人能证明我是错的,并告诉我我只是做错了。我已经为我的主程序找到了替代方案,但它们与我在这里要完成的目标不一样。

感谢所有帮助!

我想我找到了这个问题,它很棘手,我花了一些时间才找到它。虽然是一个小改动,但我会post整个事情。

我想这就是你想要的:

library("shiny")
library("shinydashboard")

header = dashboardHeader(
  title = "Dynamic UI Example"
)
sidebar = dashboardSidebar(
  sidebarMenu(
    menuItemOutput("dynamic_sidebar")
  )
)
body = dashboardBody(
  tabBox(
    tabPanel(
      strong("One")
    ),
    tabPanel(
      strong("Two")
    )
  )
)
ui = dashboardPage(header, sidebar, body)

server = shinyServer(function(input,output,session){
  output$dynamic_sidebar = renderMenu({
    sidebarMenu(
      menuItem(
        "Slider or numeric problem",
        radioButtons("slider_or_numeric",
                     label = "Slider or Numeric Input",
                     choices = c("Slider", "Numeric"),
                     selected = "Slider",
                     inline = TRUE
        )
      ),   
      uiOutput("input")  # no longer in menuItem call
    )
  })
  output$input = renderUI({
    if (input$slider_or_numeric == "Slider"){
      sliderInput("slider", 
                  label = "slider",
                  min = 0, max = 1,
                  value = 0
      )
    } else {
      numericInput("numeric", 
                   label = "numeric",
                   min = 0, max = 1,
                   value = 0
      )
    }
  })
})
shinyApp(ui, server)

我认为问题在于 uiOutput("input") 以某种方式进入了 menuItem 调用。这是 Shiny 的一个危险,Shiny 编辑器显然需要更多支持来显示这种范围。

坦率地说,我有点疑惑为什么当你玩它的时候它会出现。但是够了...

虽然我不确定我是否理解您希望它如何工作(显然这只是一个玩具示例),但它现在在启动时是这样的:

这里是在菜单扩展和通过新暴露的单选按钮控件更改输入类型之后。

所以我从另一个 SO post: 找到了一个解决方案,我有点惭愧,我在第一组搜索工作中没有设法找到它。更详细地总结一下 post 所说的内容,我在 menuItem 中渲染的 UI 元素被初始化为隐藏,默认情况下隐藏项目被暂停。作为 post 的详细信息,您可以通过 outputOptions 函数更改此选项。这是一个更新版本,完全符合我最初的要求:

library("shiny")
library("shinydashboard")

header = dashboardHeader(
    title = "Dynamic UI Example"
)
sidebar = dashboardSidebar(
    sidebarMenu(
        menuItemOutput("dynamic_sidebar")
    )
)
body = dashboardBody(
    tabBox(
        tabPanel(
            strong("One")
        ),
        tabPanel(
            strong("Two")
        )
    )
)
ui = dashboardPage(header, sidebar, body)

server = shinyServer(function(input,output,session){

    output$input <- renderUI({})
    outputOptions(output, "input", suspendWhenHidden = FALSE)

output$dynamic_sidebar = renderMenu({
        sidebarMenu(
            menuItem(
                "Slider or numeric problem",
                radioButtons("slider_or_numeric",
                   label = "Slider or Numeric Input",
                   choices = c("Slider", "Numeric"),
                   selected = "Slider",
                   inline = TRUE
                ),
                uiOutput("input")
            )     
        )
    })
    output$input = renderUI({
        if (input$slider_or_numeric == "Slider"){
            sliderInput("slider", 
                label = "slider",
                min = 0, max = 1,
                value = 0
            )
        } else {
            numericInput("numeric", 
                label = "numeric",
                min = 0, max = 1,
                value = 0
            )
        }
    })
})

shinyApp(ui, server)

请注意,在设置选项之前必须初始化输出对象,否则它将为空并导致错误。

感谢迈克试图回答这个问题,希望如果其他人偶然发现这个问题,他们会发现这个解决方案很有用。