R 中重新渲染/更新数据表后,JS 回调函数不起作用

问题描述 投票:0回答:1

我有一个闪亮的 R 应用程序,我想右键单击任意行并显示包含不同可操作项目的上下文菜单(打印右键单击行的数据)。

首次启动应用程序时,上下文菜单和可操作项目工作正常。 但是,单击“更新表”按钮(在这个可重现的示例中,只是更新/重新渲染数据表)后,右键单击时仍然会出现上下文菜单,但不同的可操作项目无法在仅显示的地方工作“未定义”而不是实际的行数据。

有谁可以解释为什么 JS() 回调函数中可操作项的行为在重新渲染数据表后不起作用?

我读过很多关于重新渲染输出后数据表的 ID 被覆盖的内容,也许回调函数无法正确指向新创建的 ID(通过参数“selector: '#mytable tr'”)。我不是当然,但如果这是原因,我仍然无法找到解决方法。

下面是完全可重现的示例:

library(shiny)
library(DT)

c1 <- c(
"$.contextMenu({",
"selector: '#mytable tr',",
"trigger: 'right',",
"callback: function(key, options) {",
"var row = table.row(options.$trigger);",
"var data = row.data();",
"var m = 'clicked: ' + key + ' ' + data;",
"var newtab = window.open('','anotherWindow', 'width=750,height=600');",
"newtab.document.write('<p> Below is the row data! </p>', '<br>',data);",
"},",
"items: {",
"'showdata': {name:'Show row data', icon: 'fa-regular fa-folder'},",
"'showsamedata': {name:'Show same row data again', icon: 'fa-regular fa-folder'}",
"}",
"})"
)

ui <- fluidPage(
  tags$head(
    tags$link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.2/jquery.contextMenu.min.css"),tags$script(src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.2/jquery.contextMenu.min.js"),tags$script(src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.2/jquery.ui.position.js"),tags$script(src="https://kit.fontawesome.com/293ef49cbe.js")
  ),
  DTOutput("mytable"),
  actionButton(inputId = "update",
           width = "150px",
           #style = "height:35px;border:3px;border-style:double;border-color:black;",
           label = div(style="vertical-align:middle;font-weight:bold","Update table"))
 )

 server <- function(input, output) {

#initial rendering
  output$mytable <- renderDataTable({
    datatable(iris, callback = JS(c1))
  })

#re-rendering
  observeEvent(input$update, {
    output$mytable <- renderDataTable({
      datatable(iris, callback = JS(c1))
    })
  })
}

shinyApp(ui, server)

On the first launch of the app and trying the context menu

After re-rendering the table by clicking on the button and trying the context menu

我尝试使用 proxyDataTables 并使用 drawCallback 函数,但没有成功。此外,我的应用程序需要能够使用回调函数而无需代理,因为实际应用程序通过具有许多过滤器的函数重新创建整个数据表,然后最终得到渲染。

我希望回调函数即使在更新/重新渲染数据表之后也能完全工作。

javascript r shiny datatables dt
1个回答
0
投票

我不知道为什么会有这种行为。它的工作原理如下,没有回调:

library(shiny)
library(DT)

c1 <- c(
  "$(document).ready(function() {",
  "  $.contextMenu({",
  "    selector: '#mytable tr',",
  "    trigger: 'right',",
  "    callback: function(key, options) {",
  "      var tbl = $('#mytable').find('table').DataTable();",
  "      var row = tbl.row(options.$trigger);",
  "      var data = row.data();",
  "      var m = 'clicked: ' + key + ' ' + data;",
  "      var newtab = window.open('','anotherWindow', 'width=750,height=600');",
  "      newtab.document.write('<p> Below is the row data! </p>', '<br>',data);",
  "    },",
  "    items: {",
  "      'showdata': {name:'Show row data', icon: 'fa-regular fa-folder'},",
  "      'showsamedata': {name:'Show same row data again', icon: 'fa-regular fa-folder'}",
  "    }",
  "  });",
  "});"
)

js <- paste0(c1, collapse = "\n")

ui <- fluidPage(
  tags$head(
    tags$link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.2/jquery.contextMenu.min.css"),tags$script(src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.2/jquery.contextMenu.min.js"),tags$script(src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.2/jquery.ui.position.js"),
    tags$script(src="https://kit.fontawesome.com/293ef49cbe.js"),
    tags$script(HTML(js))
  ),
  DTOutput("mytable"),
  actionButton(
    inputId = "update",
    width = "150px",
    #style = "height:35px;border:3px;border-style:double;border-color:black;",
    label = div(style="vertical-align:middle;font-weight:bold","Update table")
  )
)

server <- function(input, output) {
  
  #initial rendering
  output$mytable <- renderDataTable({
    datatable(iris)
  })
  
  #re-rendering
  observeEvent(input$update, {
    output$mytable <- renderDataTable({
      datatable(iris)
    })
  })
}

shinyApp(ui, server)
© www.soinside.com 2019 - 2024. All rights reserved.