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

Shiny应用中tab切换时如何实现modalDialog自动关闭

实现方案

你只需要在现有代码的基础上做两处调整即可:

  1. 补充加载tibble和dplyr包,你原代码用了tibble构造数据和mutate语法,缺了依赖会运行报错
  2. 在监听input$change的回调函数里,更新tab后新增一行removeModal()关闭弹窗,Shiny会按顺序先执行tab切换操作,再关闭弹窗,完全符合你的需求

修改后的完整可运行代码如下:

library(shiny)
library(reactable)
library(tibble)
library(dplyr)

ui = fluidPage(
  navbarPage(title = "tabs", id = "nav",
    tabPanel(title = "tabone",
      actionLink(inputId = "action", "open modalbox")
    ),
    tabPanel(title = "tabtwo")
  )
)

server = function(input, output, session){
  shinyInput = function(FUN, len, id, labels, ...) {
    inputs = character(len)
    for (i in seq_len(len)) {
      inputs[i] = as.character(FUN(paste0(id, i), label = labels[i], ...))
    }
    inputs
  }
  
  observeEvent(input$action, {
    showModal(
      modalDialog(
        tagList(reactableOutput(outputId = "table"))
      )
    )
  })
  
  output$table = renderReactable({
    data = tibble(c = "click to change navbar input") %>%
      mutate(c = shinyInput(actionButton, n(), 'id', labels = c, onclick = "Shiny.setInputValue('change', this.innerText)")) %>%
      reactable(data = .,
        sortable = FALSE,
        columns = list(
          `c` = colDef(html = TRUE)
        )
      )
  })
    
  observeEvent(input$change, {
    updateTabsetPanel(session = session, inputId = "nav", selected = "tabtwo")
    # 关闭弹窗
    removeModal()
  })  
}

shinyApp(ui, server)

如果需要严格保证tab切换完成后再关闭弹窗,也可以单独监听navbar的选中值变化,写法如下(可选,绝大多数场景上面的写法已经足够):

# 替换原来的input$change监听事件
observeEvent(input$change, {
  updateTabsetPanel(session = session, inputId = "nav", selected = "tabtwo")
})

observeEvent(input$nav, {
  if(input$nav == "tabtwo") {
    removeModal()
  }
})

内容的提问来源于stack exchange,提问作者werN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 19:36:04