3

假设我想获得以下内容(带有按钮jstreeshiny部分只是为了说明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>

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

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

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

JS 错误信息

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

闪亮应用

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)
4

1 回答 1

1

我找到了解决方案。基本上可以使用ready.jstree orloaded.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)
于 2019-09-12T16:07:35.610 回答