【问题标题】:R Shiny Dashboard - uiOutput not rendering inside tab itemsR Shiny Dashboard - uiOutput 未在选项卡项内呈现
【发布时间】:2021-05-05 22:55:50
【问题描述】:

我正在构建一个闪亮的仪表板,并希望包含一个具有动态值范围的滑块。为此,我在服务器上生成sliderInput 并使用renderUI/uiOuput 显示它。在下面的示例中,如果我只在一个tabPanel 上包含滑块,则此方法可以正常工作。但是,当我尝试将其添加到第二个 tabPanel 时,两者都无法呈现。

This post 描述了一个类似的问题,但解决方案 (suspendWhenHidden = FALSE) 对我不起作用。我也尝试了this post 的解决方案,尽管问题有所不同。

library(shinydashboard)
library(shiny)
ui <- dashboardPage(
  dashboardHeader(title = "Demo dashboard"),
  dashboardSidebar(
    sidebarMenu(
      menuItem("Overview", tabName = "overview", icon = icon("dashboard"))
    )
  ),
  dashboardBody(
    tabItems(
      tabItem(tabName = "overview",
        fluidRow(
          column(width = 6,
            tabBox(
             title = "Tab box",
             width = "100%",
             id = "tabset1", height = "250px",
             tabPanel("Tab 1",
              img(src = "test_img.jpg", height="100%", width="100%", align="center"),
              # the slider is rendered properly if only included in a single tab
              uiOutput("out_slider")
             ),
             tabPanel("Tab 2",
              img(src = "test_img.jpg", height="100%", width="100%", align="center"),
              # however, uncommenting below causes the slider to not render on *either* tab 
              #uiOutput("out_slider")
             )
            )
          )
        )
      )
    )
  )
)


server <- function(input, output) {
  
  
  startDate <- as.Date("2019-01-01","%Y-%m-%d")
  endDate <- as.Date("2020-01-01","%Y-%m-%d")
  
  # from https://stackoverflow.com/q/36613018/11434833 ... does not seem to fix problem
  # output$out_slider <- renderUI({})
  # outputOptions(output, "out_slider", suspendWhenHidden = FALSE)
  
  output$out_slider <- renderUI({
    sliderInput("slider1", label = h3("Slider"), min = startDate, 
                max = endDate, value = endDate,timeFormat="%e %b, %y")
  })
  
}

shinyApp(ui, server)

【问题讨论】:

  • 您不能两次包含相同的输出 ID。
  • 谢谢。所以我需要在服务器上制作两个单独的滑块并分别渲染?
  • 是的。或者你可以开始模块编程...有点复杂。
  • 谢谢@YBS

标签: r user-interface shiny shinydashboard


【解决方案1】:

正如YBS所说,ID有冲突。 尝试创建如下所示的模块。

library(shinydashboard)
library(shiny)

slider<-function(id){
  ns<-NS(id)
  tagList(
    uiOutput(ns("out_slider"))
  )
}

sliderServer<-function(id, label, min, 
                      max , value, timeFormat="%e %b, %y"){
  moduleServer(
    id,
    function(input,output,session){
      output$out_slider <- renderUI({
        sliderInput("slider", label , min, 
                    max, value, timeFormat="%e %b, %y")
      })
    }
  )
}


ui <- dashboardPage(
  dashboardHeader(title = "Demo dashboard"),
  dashboardSidebar(
    sidebarMenu(
      menuItem("Overview", tabName = "overview", icon = icon("dashboard"))
    )
  ),
  dashboardBody(
    tabItems(
      tabItem(tabName = "overview",
              fluidRow(
                column(width = 6,
                       tabBox(
                         title = "Tab box",
                         width = "100%",
                         id = "tabset1", height = "250px",
                         tabPanel("Tab 1",
                                  img(src = "test_img.jpg", height="100%", width="100%", align="center"),
                                  # the slider is rendered properly if only included in a single tab
                                  slider("tab1")
                         ),
                         tabPanel("Tab 2",
                                  img(src = "test_img.jpg", height="100%", width="100%", align="center"),
                                  # however, uncommenting below causes the slider to not render on *either* tab 
                                  slider("tab2")
                         )
                       )
                )
              )
      )
    )
  )
)


server <- function(input, output) {
  
  
  startDate <- as.Date("2019-01-01","%Y-%m-%d")
  endDate <- as.Date("2020-01-01","%Y-%m-%d")
  
  sliderServer("tab1",label = h3("Slider"), min = as.Date("2019-01-01","%Y-%m-%d"), 
               max = as.Date("2020-01-01","%Y-%m-%d"), value = as.Date("2020-01-01","%Y-%m-%d"), timeFormat="%e %b, %y")
  
  sliderServer("tab2", label = h3("Slider"), min = as.Date("2019-01-01","%Y-%m-%d"), 
               max = as.Date("2020-01-01","%Y-%m-%d"), value = as.Date("2020-01-01","%Y-%m-%d"), timeFormat="%e %b, %y")
  

  
}

shinyApp(ui, server)

如果您打算在sliderServer函数中传递反应值,请将其包装在observeEvent中。

【讨论】:

  • 感谢 Asitav 提供的模块示例。但是,我不清楚这样做的目的是什么,而不是简单地从我的原始示例中复制 output$out_slider &lt;- renderUI({ ... 代码块(具有不同的输出 ID)。在您的示例中,您仍然需要使用唯一 ID 调用两次 sliderServer ...那么使用模块完成了什么?
  • 谢谢尼克。在我开始使用模块之前,这也是我的问题。模块显然不会在小型应用程序中增加价值。但是考虑一下 1. 你有什么在renderUI 里面,比如说 20 行代码和 2. 你需要在你的应用程序中使用 call this 10 次在这种情况下,使用模块将减少编码和工作量。此外,您还避免了容易出错的复制粘贴。基本上,有助于管理复杂性。最后,如果您将模块保存为单独的 R 脚本或包中,您也可以在其他应用程序中使用它们。
  • 太好了,感谢您的解释....现在要弄清楚如何让每个滑块更新以在另一个更改时匹配...使用updateSliderInput很容易正常执行,但可以'当它们在标签项内时,它不能工作
  • 不客气,尼克。请问可以分享代码吗?我可以看看。顺便说一句,如果您想使用完全相同的输出,为什么不保留一个位于选项卡之外的滑块。可能是在框内或框页脚或框外的新fluidRow 中?
  • 感谢您愿意提供帮助。我实际上发现了让滑块相互更新的问题。正如您所提到的,使用一个滑块会更理想。但我希望它成为tabBox 的一部分,并且由于某种原因,如果我将它放在tabPanel 之外,我将无法渲染uiOutput。与我最初的问题类似,但这次不是因为重复的 ID,因为我只使用了一个。
猜你喜欢
  • 2017-10-14
  • 2016-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-09
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多