You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 15:49:30