我正在尝试根据用户希望提供输入的方式生成动态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)
要验证问题,在加载后只需打开菜单项,您就会看到单选按钮,但没有别的。将导航栏上的选项卡从一个切换为两个,输入应显示在菜单中(必须在菜单打开时完成)。
我真的只是抓住稻草,我已经对它进行了几个小时的故障排除,我认为这只是与这些功能不兼容。我真的希望有人可以证明我错了,并告诉我,我只是做错了。我已经为我的主程序找到了替代方案,但它们与我在这里要完成的工作没有相同的美学。
感谢您的帮助!
答案 0 :(得分: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编辑显然需要更多的支持来展示这种范围。
虽然我不完全确定我理解你希望如何使用它(显然它只是一个玩具示例),但这就是它在启动时的样子:
此后菜单扩展并通过新曝光的单选按钮控件更改输入类型。
答案 1 :(得分:1)
所以我找到了另一个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)
请注意,在设置输出对象之前必须先对其进行初始化,否则它将为null并导致错误。
感谢Mike试图回答这个问题,希望如果其他人偶然发现这个问题,他们会发现这个解决方案很有用。