带有conditionalPanel的shinydashboard中的动态菜单

时间:2017-07-27 16:16:54

标签: r shiny shinydashboard

背景

我正在尝试开发一个应用程序,它有一个登录屏幕,根据用户的权限显示不同的菜单。

用户权限是分层的,这意味着Read + Write用户应具有与Read用户相同的权利以及一些其他权限。

我现在正在努力创建这个动态菜单。我看了this document on dynamic UIs,希望我能够完全使用conditionalPanel来实现我的目标。

在下面的代码中,您会发现存在大量重复。最糟糕的是,我必须为tabs分配唯一的名称,即使它们位于不同的(互斥)面板(a1a2)中,但这些名称恰好是相同。

到目前为止尝试的事情

我尝试将conditionalPanel移动到sidebarMenu(和tabItems分别),但后来我收到错误,因为conditionalPanel的返回类型与Do A不匹配期望的类型。

预期结果

最后,我希望最小化代码重复。也就是说,我想为Do BDo A完全一次定义用户界面,但为两个用户重新使用 renderUI

我有哪些选择?我是否必须回归动态渲染(renderMenu / conditionalPanel),或者我是否有办法实现仅{/ 1}}的所需行为?

具有重复的工作代码

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))

代码段:不起作用,但至少没有重复

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

1 个答案:

答案 0 :(得分: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))

希望这有帮助!