簡體   English   中英

是否可以在 shiny 應用程序中有條件地顯示控制欄?

[英]Is it possible to conditionally show the controlbar in shiny apps?

我只想為左側欄中的幾個選項卡顯示控制欄(右側欄)。

library(shiny)
library(bs4Dash)

shinyApp(
  ui = dashboardPage(
    header = dashboardHeader(
      title = "My dashboard"
    ),
    sidebar = dashboardSidebar(
      
      sidebarMenu(
        id = "sidebarMenu",
        menuItem(
          text = "Tab 1",
          tabName = "tab1"
        ),
        menuItem(
          text = "Tab 2",
          tabName = "tab2"
        )
      )
      
    ),
    body = dashboardBody(),
    controlbar = dashboardControlbar(),
    title = "DashboardPage"
  ),
  server = function(input, output) { }
)

我嘗試開發一個 shiny 應用程序,其中對於某些選項卡,控制欄是必需的,對於其他選項卡,控制欄應該顯示某些選項,而對於其他選項卡,它是顯而易見的。 確保這一點的最優雅方法是什么? 我應該將外觀“外包”到單獨的模塊中還是有其他建議?

這是可能的,並且有很多不同的方法可以實現這一目標。 不同的方法各有優缺點。 我可以演示最常用的條件 UI 元素的基本 Shiny 方法。 每個選項卡的條件 UI 問題的“簡單”解決方案中的共同點是以某種方式評估用戶當前查看的選項卡。

第一種方法是檢查 Javascript 上下文並使用conditionalPanel調整 UI:

shinyApp(
  ui = dashboardPage(
    header = dashboardHeader(
      title = "My dashboard"
    ),
    sidebar = dashboardSidebar(
      sidebarMenu(
        id = "sidebarMenu",
        menuItem(
          text = "Tab 1",
          tabName = "tab1"
        ),
        menuItem(
          text = "Tab 2",
          tabName = "tab2"
        ),
        menuItem(
          text = "Tab 3",
          tabName = "tab3"
        )
      )
    ),
    body = dashboardBody(),
    controlbar = dashboardControlbar(
      id= "controlbar",
      collapsed = TRUE,
      conditionalPanel(
        condition = "input.sidebarMenu=='tab1'||input.sidebarMenu=='tab3'",
        controlbarMenu(
          controlbarItem(title = "Item1"),
          controlbarItem(title = "Item2")
          )
        ),
        conditionalPanel(
          condition = "input.sidebarMenu=='tab2'",
          controlbarMenu(
            controlbarItem(title = "Item3")
          )
        ),
        conditionalPanel(
          condition = "input.sidebarMenu=='tab3'",
          controlbarMenu(
          controlbarItem(title = "Item4")
          )
      )
    ),
    title = "DashboardPage"
  ),
  server = function(input, output,session) { }
)

好處顯然是渲染速度更快,因為它是在 UI(客戶端)內部進行評估的。 缺點是我們必須使用 Javascript(我們可能不想這樣做)並且我們還在 UI function 中創建邏輯,使其更加混亂。

下一個方法是使用 R 並在服務器 function 中呈現 UI 的某些部分並將其發送到 output function 在 UI 中

shinyApp(
  ui = dashboardPage(
    header = dashboardHeader(
      title = "My dashboard"
    ),
    sidebar = dashboardSidebar(
      sidebarMenu(
        id = "sidebarMenu",
        menuItem(
          text = "Tab 1",
          tabName = "tab1"
        ),
        menuItem(
          text = "Tab 2",
          tabName = "tab2"
        ),
        menuItem(
          text = "Tab 3",
          tabName = "tab3"
        )
      )
    ),
    body = dashboardBody(),
    controlbar = dashboardControlbar(
      id= "controlbar",
      collapsed = TRUE,
      sidebarMenuOutput("Menu")
      ),
    title = "DashboardPage"
  ),
  server = function(input, output,session) { 
    observeEvent(input$sidebarMenu, {
        output$Menu <- renderMenu({
          if(input$sidebarMenu=="tab1") {
          controlbarMenu(
            controlbarItem(
              title = "Item1"
            )
          )
          }else if(input$sidebarMenu=="tab2"){
            controlbarMenu(
              controlbarItem(
                title = "Item2"
              ),
              controlbarItem(
                title = "Item2_2"
              )
            )
          }else{
            controlbarMenu()
          }
        })
    })
    }
)

好處是我們的邏輯在Server function,我們的UI變得更簡潔了。 缺點是我們向服務器添加了額外的計算工作,這可以在客戶端完成。 我們還必須編寫一些if else語句或mapapply並且不清楚應該在服務器 function 中呈現多少 UI。如果你想添加一個功能它會變得更加復雜,所以你經常重寫如果您不小心並提前計划反應性等,這在開發過程中很多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM