Reactable中点击同一行后modalDialog无法弹出的问题求助
解决Reactable同一行点击无法重复触发Modal的问题
问题原因
你推测的没错:observeEvent(input$foo, ...) 默认只在input$foo的值发生变化时才会执行逻辑。当重复点击同一行时,rowInfo.id没有改变,Shiny.setInputValue传递的是同一个值,所以Shiny不会触发事件。
解决方案1:给输入值添加唯一标识(推荐)
修改onClick的JavaScript函数,每次点击时传递一个包含行ID和时间戳的对象。时间戳每次都不同,能保证input$foo的值每次点击都更新,从而触发observeEvent。
修改后的完整代码:
library(shiny) library(tidyverse) library(reactable) ui <- fluidPage( fluidRow( column(12, align = 'center', reactableOutput("tbl")) ) ) server <- function(input, output, session) { data = reactive({ mtcars %>% add_rownames('car') }) output$tbl = renderReactable( reactable( data(), defaultPageSize = 10, compact = T, highlight = T, defaultColDef = colDef(headerClass = "bar-sort-header", sortNALast = T, align = 'center', headerVAlign = 'center', vAlign = 'center', minWidth = 60 ), onClick = JS("function(rowInfo, colInfo) { // 传递包含行ID和时间戳的对象,确保每次输入值不同 Shiny.setInputValue('foo', {rowId: rowInfo.id, timestamp: Date.now()}, {priority: 'event'}); }"), rowStyle = list(cursor = "pointer") ) ) observeEvent(input$foo, { # 提取行ID row_id <- input$foo$rowId print(row_id) showModal( modalDialog( size = 'l', easyClose = T, title = data()$car[as.numeric(row_id)+1], ) ) }) } shinyApp(ui = ui, server = server)
解决方案2:使用observe替代observeEvent
如果不想修改JS,可以用observe监听input$foo,只要输入被设置就执行逻辑,无需依赖值的变化:
# 仅修改server部分的监听逻辑 server <- function(input, output, session) { data = reactive({ mtcars %>% add_rownames('car') }) output$tbl = renderReactable( reactable( data(), defaultPageSize = 10, compact = T, highlight = T, defaultColDef = colDef(headerClass = "bar-sort-header", sortNALast = T, align = 'center', headerVAlign = 'center', vAlign = 'center', minWidth = 60 ), onClick = JS("function(rowInfo, colInfo) { Shiny.setInputValue('foo', rowInfo.id) }"), rowStyle = list(cursor = "pointer") ) ) # 用observe替代observeEvent,每次input$foo被设置时都执行 observe({ req(input$foo) print(input$foo) showModal( modalDialog( size = 'l', easyClose = T, title = data()$car[as.numeric(input$foo)+1], ) ) }) }
关键说明
- 方案1通过时间戳确保输入值的唯一性,完全契合Shiny的事件触发机制,是最可靠的解决方式。
- 方案2利用
observe的特性简化逻辑,但需用req(input$foo)避免初始空值触发不必要的执行。
内容的提问来源于stack exchange,提问作者Agrosel
相关产品推荐
相关产品推荐

