R Shiny DT表格嵌入按钮分页失效的解决方案咨询
这个问题我之前也碰到过!核心原因是DT在分页、排序或搜索时会动态渲染当前页的行,你原来的callback只在表格初始化时执行了一次绑定操作,新生成的行里的按钮并没有被Shiny重新绑定,所以触发不了事件。
解决方案:使用drawCallback替代初始化callback
DT提供了drawCallback选项,它会在每次表格重绘(包括分页、排序、搜索)时自动执行,我们可以把绑定逻辑放在这里,确保每一页的按钮都能被Shiny正确识别。
下面是修改后的完整可复现代码:
library(shiny) library(DT) ui <- fluidPage( titlePanel("reprex1"), fluidRow( dataTableOutput("dt1") ) ) server <- function(input, output) { output$dt1 <- renderDataTable({ mtlocal <- mtcars # 生成Action Button列 mtlocal$actionbutton <- sapply(1:nrow(mtlocal), function(n) { as.character(actionButton( paste0("buttonpress", n), label = paste0("buttonpress", n) )) }) datatable( mtlocal, escape = FALSE, selection = "none", options = list( # 使用drawCallback替代初始化callback drawCallback = JS("function(settings) { var table = this.api(); // 遍历当前页的所有行 table.rows({page:'current'}).every(function(i, tab, row) { var $this = $(this.node()); $this.addClass('shiny-input-container'); }); // 先解绑再绑定,确保新元素被正确识别 Shiny.unbindAll(table.table().node()); Shiny.bindAll(table.table().node()); }") ) ) }, server = FALSE) # 为每个按钮绑定观察者 lapply(1:nrow(mtcars), function(x){ observeEvent(input[[paste0("buttonpress",x)]], { showModal(modalDialog( h2(paste0("You clicked on button ", x, "!")) )) }) }) } shinyApp(ui = ui, server = server)
关键修改点说明:
drawCallback替代callback:这个函数会在表格每次绘制后触发,包括分页切换、排序、搜索操作,确保新渲染的行都能被处理。- 只遍历当前页的行:
table.rows({page:'current'})只处理当前显示的行,避免不必要的性能消耗。 - 重新绑定Shiny输入:每次绘制后先执行
Shiny.unbindAll清除旧绑定,再用Shiny.bindAll绑定新元素,保证所有按钮都能和Shiny的input对象关联。
现在你测试一下,不管切换到哪一页,或者排序后把后面的行移到第一页,按钮都能正常触发弹窗了!
内容的提问来源于stack exchange,提问作者chrisR
相关产品推荐
相关产品推荐

