[英]RStudio Shiny and JavaScript communication issue
I would like to make a Shiny app which makes as much HTML div object as the lenght of selected the database, but there could be a communication problem between Shiny and JavaScript.我想制作一个 Shiny 应用程序,它可以生成与所选数据库的长度一样多的 HTML div 对象,但 Shiny 和 JavaScript 之间可能存在通信问题。
I tried to use Shiny.addCustomMessageHandler but It seems to be only sends information within the function.我尝试使用 Shiny.addCustomMessageHandler 但它似乎只在函数内发送信息。 My goal is to modify the msg variable value to ncol(database() )
我的目标是将 msg 变量值修改为 ncol(database() )
Here is a minimal example:这是一个最小的例子:
server.r服务器文件
library(shiny)
shinyServer(
function(input, output, session) {
database <- reactive({
get(input$database)
})
observe({
session$sendCustomMessage(type = 'testmessage', message = ncol(database()))
})
})
ui.r用户界面
library(shiny)
shinyUI(fluidPage(
tags$head(tags$script(src="script.js")),
fluidRow(
# TITLE
titlePanel("title"),
# SIDEBAR
sidebarPanel(width = 2,
selectInput("database", "Select sample database:", choices = c("mtcars","iris","Titanic","AirPassengers"))
)
),
# MAIN-PANEL
column(width = 8,
tabsetPanel(type = "pills",
tabPanel("view",
tags$div(id="target")
)
))
))
script.js脚本.js
$(document).on('shiny:connected', function(event) {
var msg;
Shiny.addCustomMessageHandler("testmessage",
function(message) {
msg = message;
}
);
for(var i =1; i<= msg; i++){
$('#target').append($('<div/>', { id: 'targ' + i, 'class' : 'col-md-4'}))
}
});
Thanks for any suggestion!感谢您的任何建议!
UPDATE1:更新1:
When I generates plots like this:当我生成这样的图时:
$(document).ready(function() {
Shiny.addCustomMessageHandler("testmessage",
function(message) {
updateTargetDiv(message);
}
);
});
function updateTargetDiv(msg){
node = document.getElementById('target');
while (node.hasChildNodes()) {
node.removeChild(node.lastChild);
}
for(var i =1; i<= msg; i++){
$('#target').append($('<div/>', { id: 'targ' + i, 'class' : 'col-md-4'}));
}
for(var i =1; i<= msg; i++){
$('#targ' + i).append($('<div/>', { id: 'plot' + i, 'class' : 'col-md-3 shiny-plot-output'}))
$('#targ' + i).append($('<div/>', { id: 'summary' + i, 'class' : 'col-md-1 shiny-html-output'}))
}
}
server.r服务器文件
observe({
for (i in 1:ncol(database())) {
local({
my_i = i
output[[paste0('plot',i)]] <- renderPlot({
db = database()
ggplot(data = db,
aes_string(colnames(db)[my_i])) +
geom_histogram()
})
output[[paste0('summary',i)]] <- renderTable({
db = database()
mat = matrix(NA,6,2)
mat[,1] = names(summary(db[,my_i]))
mat[,2] = summary(db[,my_i])
mat
}, include.colnames=FALSE)
})
}
})
I cannot se any plots.我看不到任何情节。 Why?
为什么? (It works without JavaScript dynamic div script)
(它在没有 JavaScript 动态 div 脚本的情况下工作)
Based on your description, I think the main problem is that you only call your JavaScript function once.根据您的描述,我认为主要问题是您只调用了一次 JavaScript 函数。
.on('shiny:connected' ...
is only called once at the start. .on('shiny:connected' ...
在开始时只调用一次。
Another issue is that you are only ever adding to the target div
, so it will keep growing unless you clear its children div
elements.另一个问题是您只会添加到目标
div
,因此除非您清除其子div
元素,否则它将继续增长。
I think the code below will suit your needs.我认为下面的代码将满足您的需求。 It creates the CustomMessageHandler once and will call the
updateTargetDiv
any time a new value is passed in. It also clears the children div
elements from target before creating the new ones.它创建CustomMessageHandler一次,将调用
updateTargetDiv
一个新值传入任何时候,它还会清除孩子div
从目标元素创建新的之前。
$(document).ready(function() {
Shiny.addCustomMessageHandler("testmessage",
function(message) {
updateTargetDiv(message);
}
);
});
function updateTargetDiv(msg){
node = document.getElementById('target');
while (node.hasChildNodes()) {
node.removeChild(node.lastChild);
}
for(var i =1; i<= msg; i++){
$('#target').append($('<div/>', { id: 'targ' + i, 'class' : 'col-md-4'}));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.