2017-07-27 111 views
1

背景動態菜單,conditionalPanel

我想開發一個應用程序,它有一個登錄屏幕,顯示根據用戶的權限不同的菜單。

用戶權限是分層的,這意味着Read + Write用戶應該擁有與Read用戶相同的權利以及一些其他權利。

我現在正在努力如何創建這個動態菜單。我讀this document on dynamic UIs,我希望我完全可以通過使用conditionalPanel來實現我的目標。

在下面的代碼中,您會看到有很多重複。最糟糕的是,即使它們在不同的(互斥)面板(a1a2)中,但我們也必須爲tabs分配唯一的名稱,但其意圖完全相同。

事情試過到目前爲止

我試圖移動(分別tabItems)的conditionalPanelsidebarMenu,但後來我得到一個錯誤,因爲conditionalPanel返回類型不匹配預期的類型。

預期結果

最後,我想有很少的代碼重複。也就是說,我想定義的界面爲Do ADo B正好爲一次,但重複使用Do A兩個用戶。

我有哪些選擇?我是否必須回退到動態渲染(renderUI/renderMenu),或者有什麼方法可以實現預期的行爲(僅限於conditionalPanel)?

工作代碼複製

library(shiny) 
library(shinydashboard) 

ui <- dashboardPage(
    dashboardHeader(), 
    dashboardSidebar(
     selectInput("userrights", label = "User Rights:", 
        choices = c("Read + Write", "Read")), 
     conditionalPanel("input.userrights == 'Read'", 
         sidebarMenu(
          menuItem("Do A", tabName = "a1") 
         ) 
    ), 
     conditionalPanel("input.userrights == 'Read + Write'", 
         sidebarMenu(
          ## unnecessary duplication + I need yet another tab 'a2' 
          menuItem("Do A", tabName = "a2"), 
          menuItem("Do B", tabName = "b2") 
         ) 
    ) 
    ), 
    dashboardBody(
     conditionalPanel("input.userrights == 'Read'", 
         tabItems(
          tabItem("a1", h1("A was done")) 
         ) 
    ), 
     conditionalPanel("input.userrights == 'Read + Write'", 
         tabItems(
          tabItem("a2", h1("A was done")), 
          tabItem("b2", h1("B was done")) 
         ) 
    ) 
    ) 
) 

server <- function(input, output) {} 

runApp(shinyApp(ui, server)) 

段:沒有工作,但至少W/O複製

sidebarMenu(
    menuItem("Do A", tabName = "a") 
    conditionalPanel("input.userrights == 'Read + Write'", 
     menuItem("Do B", tabName = "b") 
    ) 
) 

回答

1

您可以在服務器中呈現的菜單根據用戶輸入或其他條件,並將其輸出到UI。下面的工作示例:

library(shiny) 
library(shinydashboard) 

ui <- dashboardPage(
    dashboardHeader(), 
    dashboardSidebar(
    selectInput("userrights", label = "User Rights:", 
       choices = c("Read + Write", "Read")), 
    sidebarMenuOutput("menu") 
), 
    dashboardBody(
    tabItems(
     tabItem("a", h1("A was done")), 
     tabItem("b", h1("B was done")) 
    ) 
) 
) 

server <- function(input, output) { 


    output$menu <- renderMenu({ 

    my_list = list(menuItem("a", tabName="a")) 

    if(input$userrights=="Read + Write") 
     my_list[[2]] = menuItem("b", tabName="b") 

    sidebarMenu(my_list) 

    }) 

} 

runApp(shinyApp(ui, server)) 

希望這有助於!

+0

感謝您的回答+1。所以假設最好的辦法是回到'renderMenu'? – thothal