首页 > 解决方案 > updateTabsetPanel 在 Shiny 应用程序中的嵌套 tabsetPanel 之间导航

问题描述

我希望能够使用 anactionLink导航到tabPanel嵌套 s 中tabsetPanel的 s。tabPanel如果我已经选择了父母,我目前只能导航到特定的tabPanel。这个命名法很快就会变得混乱,所以这里有一个嵌套的例子,tabPanels两个actionLinks 导航到两个 child tabPanels:

library(shiny)

ui <- {
    fluidPage(
        fluidRow(
            column(3,
                actionLink('subpanel_1a', 'Go to 1 A'),
                br(),
                actionLink('subpanel_1b', 'Go to 1 B')
            ),
            column(9,
                tabsetPanel(id = 'master_panel',
                    tabPanel('Primary panel 1',
                        tabsetPanel(id = 'primary_panel_1',
                            tabPanel('subpanel_1_a'),
                            tabPanel('subpanel_1_b')
                        )
                    ),
                    tabPanel('Primary panel 2',
                        tabsetPanel(id = 'primary_panel_2',
                            tabPanel('subpanel_2_a'),
                            tabPanel('subpanel_2_b')
                        )
                    )
                )
            )
        )
    )
}

server <- function(input, output, session) {
    observeEvent(input$subpanel_1a, {
        updateTabsetPanel(session, 'primary_panel_1', 'subpanel_1_a')
    })
    observeEvent(input$subpanel_1b, {
        updateTabsetPanel(session, 'primary_panel_1', 'subpanel_1_b')
    })
}

shinyApp(ui, server)

actionLinks 'Go to 1 A' 和 'Go to 1 B' 仅在当前选择的父级是 'Primary panel 1' 时才有效——tabPanel如果您在 'Primary panel 2' 中它们不起作用。

actionLink无论您当前选择的面板如何,有没有办法绕过此行为以使s 正常工作?

标签: rshiny

解决方案


master_panel在更新子面板之前,您可以使用相同的“更新逻辑” 。

因此,对于 2a,它将显示为:

observeEvent(input$subpanel_2a, {
    updateTabsetPanel(session, inputId = 'master_panel', selected = 'Primary panel 2')
    updateTabsetPanel(session, inputId = 'primary_panel_2', selected = 'subpanel_2_a')
  })

可重现的代码:

library(shiny)

ui <- {
  fluidPage(
    fluidRow(
      column(3,
             actionLink('subpanel_1a', 'Go to 1 A'),
             br(),
             actionLink('subpanel_1b', 'Go to 1 B'),
             br(),
             actionLink('subpanel_2a', 'Go to 2 A'),
             br(),
             actionLink('subpanel_2b', 'Go to 2 B')
      ),
      column(9,
             tabsetPanel(id = 'master_panel',
                         tabPanel('Primary panel 1',
                                  tabsetPanel(id = 'primary_panel_1',
                                              tabPanel('subpanel_1_a'),
                                              tabPanel('subpanel_1_b')
                                  )
                         ),
                         tabPanel('Primary panel 2',
                                  tabsetPanel(id = 'primary_panel_2',
                                              tabPanel('subpanel_2_a'),
                                              tabPanel('subpanel_2_b')
                                  )
                         )
             )
      )
    )
  )
}

server <- function(input, output, session) {
  observeEvent(input$subpanel_1a, {
    updateTabsetPanel(session, inputId = 'master_panel', selected = 'Primary panel 1')
    updateTabsetPanel(session, inputId = 'primary_panel_1', selected = 'subpanel_1_a')
  })

  observeEvent(input$subpanel_1b, {
    updateTabsetPanel(session, inputId = 'master_panel', selected = 'Primary panel 1')
    updateTabsetPanel(session, inputId = 'primary_panel_1', selected = 'subpanel_1_b')
  })

  observeEvent(input$subpanel_2a, {
    updateTabsetPanel(session, inputId = 'master_panel', selected = 'Primary panel 2')
    updateTabsetPanel(session, inputId = 'primary_panel_2', selected = 'subpanel_2_a')
  })

  observeEvent(input$subpanel_2b, {
    updateTabsetPanel(session, inputId = 'master_panel', selected = 'Primary panel 2')
    updateTabsetPanel(session, inputId = 'primary_panel_2', selected = 'subpanel_2_b')
  })
}

shinyApp(ui, server)

按照这种方式,您可能会创建一些重复的代码。

根据您拥有的面板和子面板的数量,您可以尝试选择可以避免此更新的非常重复代码的名称。所以如果你有panel_1panel_1_apanel_5panel_5_d。您可以从字符串中动态读取“级别”。逻辑是panel_{FIRSTLEVELNR}_{SECONDLEVELNR}。然后你可以使用类似的东西:

library(magrittr)
levels = panel_{FIRSTLEVELNR}_{SECONDLEVELNR} >%> strsplit(split = "_") %>% unlist
updateTabsetPanel(session, inputId = 'master_panel', selected = levels[2])
updateTabsetPanel(session, inputId = 'primary_panel_1', selected = levels[3])

动态地为所有面板+子面板而不是重复 20 次。但就像我说的,这取决于您拥有的面板+子面板的数量以及所需的命名约定。


推荐阅读