Shiny Dashboard中跟踪展开的子菜单问题
Shiny Dashboard中跟踪展开的子菜单问题
嗨,我完全明白你遇到的困扰!input$sidebarItemExpanded这个输入对象确实只能追踪**顶级的menuItem**的展开状态,对于嵌套在它里面的二级及以下子菜单,它是没办法直接捕捉到的——这属于shinydashboard组件的设计局限,但我们可以通过一点点JavaScript代码轻松解决这个问题。
下面我补全了你未写完的可复现代码,同时添加了监听子菜单状态的逻辑,让你能在R端实时获取子菜单的展开/折叠状态:
library(shiny) library(shinydashboard) library(shinydashboardPlus) ui <- function(){ shinydashboardPlus::dashboardPage( shinydashboardPlus::dashboardHeader(title = "title1"), sidebar = shinydashboard::dashboardSidebar( shinydashboard::sidebarMenu( id = "sidebarItemSelected", shinydashboard::menuItem( "Scores", expandedName = "Scores", startExpanded = TRUE, selected = TRUE, dateRangeInput("dateRange", "Select Date Range"), # 嵌套的子菜单示例 shinydashboard::menuItem( "Detailed Scores", expandedName = "DetailedScores", menuSubItem("Daily Scores", tabName = "daily"), menuSubItem("Weekly Scores", tabName = "weekly") ), shinydashboard::menuItem( "Summary Scores", expandedName = "SummaryScores", menuSubItem("Monthly Summary", tabName = "monthly") ) ), shinydashboard::menuItem( "Settings", expandedName = "Settings", menuSubItem("User Settings", tabName = "user") ) ) ), body = shinydashboard::dashboardBody( # 监听子菜单展开/折叠的JavaScript代码 tags$script(HTML(" // 监听子菜单展开事件 $(document).on('shown.bs.collapse', '.treeview-menu', function() { // 获取对应父级menuItem的expandedName属性 var parentExpandedName = $(this).closest('.treeview').find('a').attr('data-expanded'); // 将状态传递给Shiny的input对象 Shiny.setInputValue('submenuExpanded', parentExpandedName); }); // 监听子菜单折叠事件 $(document).on('hidden.bs.collapse', '.treeview-menu', function() { var parentExpandedName = $(this).closest('.treeview').find('a').attr('data-expanded'); // 折叠时清空状态值 Shiny.setInputValue('submenuExpanded', ''); }); ")), shinydashboard::tabItems( shinydashboard::tabItem(tabName = "daily", h3("Daily Scores Content")), shinydashboard::tabItem(tabName = "weekly", h3("Weekly Scores Content")), shinydashboard::tabItem(tabName = "monthly", h3("Monthly Summary Content")), shinydashboard::tabItem(tabName = "user", h3("User Settings Content")) ), # 展示当前菜单展开状态的面板 fluidRow( box(title = "当前菜单展开状态", width = 12, verbatimTextOutput("menuStatus")) ) ) ) } server <- function(input, output, session) { output$menuStatus <- renderPrint({ cat("顶级展开菜单:", input$sidebarItemExpanded, "\n") cat子展开菜单:", input$submenuExpanded, "\n") }) } shinyApp(ui, server)
关键逻辑说明:
- shinydashboard的菜单折叠功能基于Bootstrap的collapse组件,所以我们监听它的
shown.bs.collapse(展开)和hidden.bs.collapse(折叠)事件。 - 通过DOM选择器找到子菜单对应的父级
menuItem,提取它的expandedName属性,再通过Shiny.setInputValue把状态传递给R端的input$submenuExpanded。 - 在server端,你就可以通过
input$submenuExpanded判断哪个子菜单处于展开状态了。
如果你的项目里有更深层级的菜单(比如三级菜单),只需要微调JS代码里的DOM选择器,找到对应层级的菜单标识即可。
备注:内容来源于stack exchange,提问作者Youngun
相关产品推荐
相关产品推荐

