【问题标题】:R Shiny: Change tabs from within a moduleR Shiny:从模块内更改选项卡
【发布时间】:2021-12-11 06:17:27
【问题描述】:

我有一个带有多个选项卡的闪亮应用程序,我希望在选项卡中包含允许用户切换选项卡的操作按钮。我找到了以下页面:https://www.titanwolf.org/Network/q/e6b187b8-6cad-4ece-ad16-7ec73ed2f758/y How to switch between shiny tab panels from inside a module?,这似乎表明问题是范围/命名空间错误,但他们没有完全解释正在发生的事情,而且我没有足够的声誉点来评论另一个要求澄清的 stackoverflow 帖子。

这是我的示例代码:

modtab1_ui <- function(id) {
  ns <- NS(id)
  tabPanel(title = 'Tab 1',
           value = NS(id, 'tab.1'),
           
           h4('This is the first tab'),
           actionButton(NS(id, 'nexttab'), 'Next Tab')
           
          )
}

modtab1_server <- function(id) {
  moduleServer(id,
               function(input, output, session) {
                 observeEvent(input$nexttab, {
                   updateTabsetPanel(session = session, inputId = NS(id, 'tabs'), selected = NS(id, 'tab.2'))
                   print('button clicked')
                 })
               })
}

modtab2_ui <- function(id) {
  ns <- NS(id)
  tabPanel(title = 'Tab 2',
           value = NS(id, 'tab.2'),
           
           h4('This is the second tab'),
          )
}


ui <- fluidPage(
  tabsetPanel(
    id = 'tabs',
    modtab1_ui('tab1'),
    modtab2_ui('tab1')
  )
)

server <- function(input, output, session) {
  modtab1_server('tab1')
}

shinyApp(ui = ui, server = server)

编辑说明新问题

modtab1_ui <- function(id) {
  ns <- NS(id)
  tabPanel(title = 'Tab 1',
           value = NS(id, 'tab.1'),

           h4('This is the first tab'),
           actionButton(NS(id, 'nexttab'), 'Next Tab'),

           textInput(NS(id,'userid'), 'User ID'),
           textOutput(NS(id, 'useridout'))
          )
}

modtab1_server <- function(id) {
  moduleServer(id,
               function(input, output, session) {
                 observeEvent(input$nexttab, {
                   updateTabsetPanel(session = session, inputId =  'tabs', selected = NS('tab2', 'tab.2'))
                   print('button clicked'),
                 })
                 
                 output$useridout <- renderText(input$userid)
               })
}

modtab2_ui <- function(id) {
  ns <- NS(id)
  tabPanel(title = 'Tab 2',
           value = NS(id, 'tab.2'),

           h4('This is the second tab'),
           actionButton(NS(id, 'firsttab'), 'First Tab'),

           textInput(NS(id, 'userid'), 'User ID'),
           textOutput(NS(id, 'useridout'))
          )
}

modtab2_server <- function(id) {
  moduleServer(id,
               function(input, output, session) {
                 observeEvent(input$firsttab, {
                   updateTabsetPanel(session = session, inputId =  'tabs', selected = NS('tab1', 'tab.1'))
                   print('button clicked'),
                 })
                 
                 output$useridout <- renderText(input$userid)
               })
}


ui <- fluidPage(
  tabsetPanel(
    id = 'tab1-tabs',
    modtab1_ui('tab1'),
    modtab2_ui('tab2')
  )
)

server <- function(input, output, session) {
  modtab1_server('tab1')
  modtab2_server('tab2')
}

shinyApp(ui = ui, server = server)

再次编辑 我在一个新问题中提出了这个问题,得到了回答:Shiny modules: switch tabs from within modules that have different namespaces

【问题讨论】:

    标签: r shiny namespaces scoping shinymodules


    【解决方案1】:

    我认为这就是您要寻找的。做了两个很小的改动!一,在 modtab1_server 函数中,我将ns(id, 'tabs') 更改为只是'tabs'。我认为由于 inputId 在模块内,它已经添加了 id,在这种情况下意味着它添加了 tab1。使用您现有的代码,我认为 tabsetPanel 的 id 是“tab1-tab1-tabs”,因此通过删除 ns(id) 它应该将 inputId 调用为“tab1-tabs”。第二个更改是将 tabsetPanel id 设置为“tab1-tabs”,以封装模块将“tab1”添加到 updateTabsetPanel 的 inputId 的方式。

    modtab1_ui <- function(id) {
      ns <- NS(id)
      tabPanel(title = 'Tab 1',
               value = NS(id, 'tab.1'),
               
               h4('This is the first tab'),
               actionButton(NS(id, 'nexttab'), 'Next Tab')
               
      )
    }
    
    modtab1_server <- function(id) {
      moduleServer(id,
                   function(input, output, session) {
                     observeEvent(input$nexttab, {
                       updateTabsetPanel(session = session, inputId = 'tabs', selected = NS(id, 'tab.2'))
                       print('button clicked')
                     })
                   })
    }
    
    modtab2_ui <- function(id) {
      ns <- NS(id)
      tabPanel(title = 'Tab 2',
               value = NS(id, 'tab.2'),
               
               h4('This is the second tab'),
      )
    }
    
    
    ui <- fluidPage(
      tabsetPanel(
        id = 'tab1-tabs',
        modtab1_ui('tab1'),
        modtab2_ui('tab1')
      )
    )
    
    server <- function(input, output, session) {
      modtab1_server('tab1')
    }
    
    shinyApp(ui = ui, server = server)
    

    【讨论】:

    • 如果我想在不同的模块中使用不同的 ID,我该如何处理?例如,如果我想在每个模块 ui 中都有一个 input$userid,我想我需要调用modtab1_ui('tab1')modtab2_ui('tab2')。但这在切换选项卡时会导致问题。如果我将actionButton 添加到切换回tab1 的modtab2,使用不同的ID(tab1 和tab2)可以让我从1 到2,但不能从2 回到1。我编辑了我的初始问题以包括您建议的更改和说明我现在要做的事情。
    • 开个玩笑,我问了一个新问题 (stackoverflow.com/questions/69831550/…) 并在那里得到了回答
    猜你喜欢
    • 2021-05-05
    • 1970-01-01
    • 2017-04-06
    • 2018-08-03
    • 2011-08-04
    • 1970-01-01
    • 2020-08-03
    • 2016-01-08
    • 2020-04-14
    相关资源
    最近更新 更多