【问题标题】:R Shiny Dashboard does not load rendered UI inside of sidebarMenu on initializationR Shiny Dashboard 不会在初始化时在侧边栏菜单内加载渲染 UI
【发布时间】:2017-08-22 04:44:04
【问题描述】:

我正在尝试根据用户希望如何提供输入来生成动态的 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)

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

我真的只是抓住了稻草,我已经解决了几个小时的问题,我认为这只是与这些功能不兼容。我真的希望有人能证明我错了,并告诉我我只是做错了。我已经为我的主程序找到了替代方案,但它们的美感与我在这里尝试完成的不同。

感谢您的所有帮助!

【问题讨论】:

    标签: r user-interface shiny shinydashboard


    【解决方案1】:

    我想我找到了这个问题,这很棘手,我花了一段时间才找到它。虽然是个小改动,但我会把整件事都贴出来。

    我想这就是你想要的:

    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 编辑器显然需要更多支持来显示这种范围。

    坦率地说,我有点不明白为什么当你玩它时它会出现。不过够了……

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

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

    【讨论】:

    • 输入在 menuItem 内,因为我希望它显示在 UI 中。我有几个侧边栏菜单,其中显示的一个随着侧边栏顶部的下拉选择而变化。在每个 sidebarMenu 中,我有 4 到 12 个输入选项,因此我一次将它们分组到 menuItems 4 中。这样我可以将所有 12 个内容都放在侧边栏中,而无需一次显示 12 个内容,用户可以选择他们想要更改的输入类别。到目前为止,我的解决方案是将滑块和数字放在不同的 menuItems 中并让它们共存,但这与我希望的视觉效果不同。
    • (新来的,我希望重复评论不是坏习惯!)我或多或少地放弃了这个作为解决方案,我玩弄了很多不同的东西,但我没有不认为有可能做我想做的事。我只是作为最后的手段来到这里,以防有人以前看到过这个特定问题并找到了解决方案。感谢您的努力!
    【解决方案2】:

    所以我从另一篇 SO 帖子中找到了解决方案:r shiny - uiOutput not rendering inside menuItem,我有点惭愧,我在第一组搜索工作中没有找到这个。综上所述,我在 menuItem 内渲染的 UI 元素被初始化为隐藏,隐藏项默认处于暂停状态。作为帖子的详细信息,您可以通过 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)
    

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

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

    【讨论】:

    • 不错的一个。当我搜索时也会发生在我身上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 2020-05-27
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多