添加元素后触发 JavaScript 代码
Fire JavaScript code once element is added
假设我想在 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 代码按预期工作)。使用优先级也无济于事。
我可以使用一个 javascript 事件处理程序,我将附加到 $(document)
,它监听树的创建吗?
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.jstree
或 loaded.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)
假设我想在 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 代码按预期工作)。使用优先级也无济于事。
我可以使用一个 javascript 事件处理程序,我将附加到 $(document)
,它监听树的创建吗?
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.jstree
或 loaded.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)