2017-10-20 9 views
0

J'ai besoin de rendre différents sous-éléments de menu en fonction de certaines valeurs de données réactives. Pour chaque sous-item, j'ai aussi besoin d'associer la sortie liée. J'ai essayé de lier avec tabName, mais je ne sais pas ce qui s'est mal passé.Shiny Dashboard: Rend plusieurs éléments de menu et affiche un contenu dynamique à chacun

Voici un exemple. La sortie désirée sera une boîte pour chaque élément de menu/sous-élément.

## This code snippet doesn't do what I need ---- 
shinyApp(
    ui = dashboardPage(
    dashboardHeader(), 
    dashboardSidebar(
     sidebarMenu(
     menuItemOutput("dynamic_menu"), 
     menuItem("Menu2", tabName = "menu2") 
    ) 
    ), 
    dashboardBody(
     tabItems(
     uiOutput("menu1_content"), 
     tabItem(tabName = "menu2", box("I am menu2")) 
    ) 
    ), 
    title = "Example" 
), 

    server = function(input, output) { 
    output$dynamic_menu <- renderMenu({ 
     submenu_list <- lapply(letters[1:5], function(x) { 
     menuSubItem(x, tabName = paste0("menu1-", x)) 
     }) 
     menuItem(
     text = "Menu1", 
     startExpanded = TRUE, 
     do.call(tagList, submenu_list) 
    ) 
    }) 

    output$menu1_content <- renderUI({ 
     content_list <- lapply(letters[1:5], function(x) { 
     tabItem(
      tabName = paste0("menu1-", x), 
      box(x) 
     ) 
     }) 
     do.call(tagList, content_list) 
    }) 
    } 
) 


## This code snippet does what I need ---- 
shinyApp(
    ui = dashboardPage(
    dashboardHeader(), 
    dashboardSidebar(
     sidebarMenu(
     menuItem(
      "Menu1", startExpanded = TRUE, 
      menuSubItem("a", tabName = "menu1-a"), 
      menuSubItem("b", tabName = "menu1-b"), 
      menuSubItem("c", tabName = "menu1-c"), 
      menuSubItem("d", tabName = "menu1-d"), 
      menuSubItem("e", tabName = "menu1-e") 
     ), 
     menuItem("Menu2", tabName = "menu2") 
    ) 
    ), 
    dashboardBody(
     tabItems(
     tabItem(tabName = "menu1-a", box("a")), 
     tabItem(tabName = "menu1-b", box("b")), 
     tabItem(tabName = "menu1-c", box("c")), 
     tabItem(tabName = "menu1-d", box("d")), 
     tabItem(tabName = "menu1-e", box("e")), 
     tabItem(tabName = "menu2", box("I am menu2")) 
    ), 
     title = "Example" 
    ) 
), 
    server = function(input, output) {} 
) 

Répondre

0

Répondre à ma propre question, mais n'hésitez pas à intervenir si vous avez quelque chose de plus élégant.

Je pense que ma compréhension initiale du tableau de bord brillant est incorrecte, ce qui rend la structure de l'application invalide.

L'astuce ici est d'ajouter id au sidebarMenu, afin que le focus de page puisse être suivi et analysé plus tard. Ensuite, chaque fonction de rendu écoutera l'entrée et rendra le contenu associé.

shinyApp(
    ui = dashboardPage(
    dashboardHeader(), 
    dashboardSidebar(
     sidebarMenu(
     id = "sidebar_menu", 
     menuItemOutput("dynamic_menu"), 
     menuItem("Menu2", tabName = "menu2") 
    ) 
    ), 
    dashboardBody(
     uiOutput("menu1_content"), 
     uiOutput("menu2_content") 
    ), 
    title = "Example" 
), 
    server = function(input, output, session) { 
    output$dynamic_menu <- renderMenu({ 
     menu_list <- lapply(letters[1:5], function(x) { 
     menuSubItem(x, tabName = paste0("menu1-", x)) 
     }) 
     menuItem(
     text = "Menu1", 
     startExpanded = TRUE, 
     do.call(tagList, menu_list) 
    ) 
    }) 

    output$menu1_content <- renderUI({ 
     sidebar_menu <- tstrsplit(input$sidebar_menu, "-") 
     if (sidebar_menu[[1]] == "menu1") box(sidebar_menu[[2]]) 
    }) 

    output$menu2_content <- renderUI({ 
     sidebar_menu <- tstrsplit(input$sidebar_menu, "-") 
     if (sidebar_menu[[1]] == "menu2") box("I am menu2") 
    }) 
    } 
)