javascript - 添加元素后触发 JavaScript 代码

标签 javascript r shiny jstree shinytree

假设我想在 shiny 中获得以下 jstree (带有按钮的部分只是为了说明 shinytree 不是从一开始就出现):

$(function() {
  $('#create').on('click', function() {
    $('#mytree').jstree({
      'core' : {
        'data' : {
          "url" : "//www.jstree.com/fiddle/?lazy",
          "data" : function (node) {
            return { "id" : node.id };
          }
        }
      },
      contextmenu : {
        items : {
          'item1' : {
            'label' : 'item1',
            'action' : function () { /* action */ }
          }
        }
      },
      plugins : ["contextmenu"]
    });
  })
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.8/themes/default/style.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.8/jstree.min.js"></script>

<div id="mytree"></div>
<button id = "create">
   Create Tree
</button>

问题是我无法通过 shinyTree 提供 contextmenu。所以我需要回退到 JavaScript 来自己添加这个功能。在控制台上,我会这样做:

$('#mytree').jstree(true).settings.contextmenu = {
   items: {
      item1 : {
         'label' : 'item1',
         'action': function() { /* action */ }
      }
   }
}

但是我应该在我的 ShinyApp 中何时何地调用它?我使用另一个处理程序的方法不起作用,因为我猜想处理程序在渲染树之前触发(然后第二次按下按钮就可以了,至少表明 JS 代码按预期工作)。使用优先级也无济于事。

JS Error Message

我可以使用附加到 $(document) 的 javascript 事件处理程序,它会监听树的创建吗?

ShinyApp

library(shiny)
library(shinyTree)
library(shinyjs)
js_code <- "$('#mytree').jstree(true).settings.contextmenu = {
   items: {
      item1 : {
         'label' : 'item1',
         'action': function() { /* action */ }
      }
   }
};"
ui <- fluidPage(useShinyjs(),
                actionButton("create", "Create Tree"), 
                shinyTree("mytree", contextmenu = TRUE))

server <- function(input, output, session) {
   ## does not work as intended
   observeEvent(input$create, runjs(js_code), ignoreInit = TRUE, priority = -1)


   output$mytree <- renderTree({
     req(input$create)
     list("Root Node" = list("Child Node 1" = list(
                                                "Child Node 3" = "", 
                                                "Child Node 4" = ""),
                             "Child Node 2" = ""))
   }) 
}

shinyApp(ui, server)

最佳答案

我找到了解决方案。基本上可以使用 ready.jstreeloaded.jstree 事件:

library(shiny)
library(shinyTree)
library(shinyjs)
js_code <- "$('.shiny-tree').on('ready.jstree', function() {
   $(this).jstree(true).settings.contextmenu = {
      items: {
         item1 : {
            'label' : 'item1',
            'action': function() { /* action */ }
         }
      }
   };
})"
ui <- fluidPage(useShinyjs(),
                actionButton("create", "Create Tree"), 
                shinyTree("mytree", contextmenu = TRUE))

server <- function(input, output, session) {
   session$onFlushed(function() runjs(js_code))

   output$mytree <- renderTree({
     req(input$create)
     list("Root Node" = list("Child Node 1" = list(
                                                "Child Node 3" = "", 
                                                "Child Node 4" = ""),
                             "Child Node 2" = ""))
   }) 
}

shinyApp(ui, server)

关于javascript - 添加元素后触发 JavaScript 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57889966/

相关文章:

javascript - 使用HTML/Javascript中的Analytics(分析)跟踪 strip 转换

javascript - 如何在用户完成输入表单时更改 div 的背景(如进度条)?

R 函数使用 .和~

r - 如何在两个不同的数据帧上运行 cor.test()

r - 根据 Shiny 中选定的行更改数据值

R Shiny 从 numericInput 数据表列中提取值

javascript - 将 AJAX 响应放入 HTML 格式

javascript - 在页面刷新时以正确的数字启动字符计数器

r - 在 R 的 data.table 中 foverlap 的一次迭代中查找所有重叠

r - 在Shiny中获取用户IP