【问题标题】:R Shiny: Run JS after HTMLwidget rendersR Shiny:在 HTMLwidget 呈现后运行 JS
【发布时间】:2020-10-28 20:47:06
【问题描述】:

community.rstudio cross-post here

我正在使用来自 visNetwork 开发版本的 HTML 小部件。

我想在该小部件中的一个按钮上设置一个事件侦听器。但是,仅在 $(document).ready(function() 中添加该事件侦听器是行不通的,因为该按钮直到 Shiny 服务器呈现小部件输出后才存在。

我将在下面添加三个部分,其中包含我尝试的解决方案、一个代表和对我的问题的更详细的解释。谢谢! :)

尝试的解决方案

我尝试定义一个setEventListener 函数(在一个字符串中),然后在服务器中运行js$startEventListener。那么问题来了:我会把它放在服务器的什么位置?

它需要在 visNetwork 渲染函数 (renderVisNetwork) 之后运行。如果我把它放在renderVisNetwork 中,它就会运行得太快(直到renderVisNetwork 完成 运行之后,该按钮才存在)。我尝试制作一个renderVisNetwork 递增的虚拟输入值(然后每次renderVisNetwork 终止时使用observeEvent 运行js$startEventListener),但这不知何故让我陷入了无限循环,而且看起来有点hacky。

我还认为this google groups post 可能会有所帮助,但我尝试了session$onFlushed 解决方案,但没有任何效果。

代表

library(shiny)
library(visNetwork) 
# Note: requires devel visNetwork. `devtools::install_github("datastorm-open/visNetwork")`

ui <- fluidPage(
  tags$head(
    tags$script(
      type = "text/javascript",
      '
      $(document).ready(function() {
      
      // Positive control: an alert for a button
      $("#clickme").click(
        function() {
            alert("Here is an alert!");
        });
        
      // This is what I am having trouble with
      $("#editedge-saveButton").click(
        function() {
          alert("Thanks for saving!")
        });
  
      })
      '
    )
  ),
  actionButton("clickme", "Click me for an alert!"),
  visNetworkOutput("mygraph")
)

server <- function(input, output, session) {
  output$mygraph <- renderVisNetwork(
    visNetwork(
      nodes = data.frame(id = "A", label = "A"),
      edges = data.frame(to = "A", from = "A", label = "A to A")
    ) %>%
      visOptions(manipulation = list(
        enabled = TRUE,
        editEdgeCols = c("label")
      ))
  )
}

shinyApp(ui, server)

更多详情

在 visNetwork 中,您可以“编辑”一条边,如下所示:

我想在用户按下“保存”按钮时调用一个函数。

那个按钮有一个id:

我可以尝试像这样向该 id 添加事件侦听器:

$("#editedge-saveButton").click(
    function() {
        alert("Thanks for saving!")
    });

但它不起作用,即使测试按钮的类似事件侦听器确实起作用:

请注意,如果我在加载应用程序后在控制台中添加该事件侦听器,它就可以正常工作:

这符合我的想法,即我的事件侦听器代码没有任何问题,只是在执行主 JS 代码时 visNetwork 小部件不存在。

【问题讨论】:

    标签: javascript r shiny


    【解决方案1】:

    这是处理这种情况的经典方法:

    $("body").on("click", "#editedge-saveButton", 
      function() {
        alert("Thanks for saving!")
      }
    );
    

    通过这种方式,单击事件处理程序附加到body 元素,但它仅在"#editedge-saveButton" 元素上发生单击时触发。

    htmlwidgets 特有的另一种方法是使用onRender 函数:

    visNetwork(
      nodes = data.frame(id = "A", label = "A"),
      edges = data.frame(to = "A", from = "A", label = "A to A")
    ) %>%
      visOptions(manipulation = list(
        enabled = TRUE,
        editEdgeCols = c("label")
      )) %>% 
      onRender(c(
        "function(el, x){",
        "  $('#editedge-saveButton').on('click', function(){"
        "    ......",
        "  });",
        "}"))
    

    (为onRender函数加载htmlwidgets包)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-09
      • 2016-07-31
      • 1970-01-01
      • 1970-01-01
      • 2019-07-01
      • 2019-03-04
      • 1970-01-01
      • 2020-02-04
      相关资源
      最近更新 更多