RStudio Shiny和JavaScript通信问题

时间:2017-01-21 20:41:57

标签: javascript r shiny

我想创建一个Shiny应用程序,它可以生成与选择数据库的长度相同的HTML div对象,但是Shiny和JavaScript之间可能存在通信问题。

我尝试使用Shiny.addCustomMessageHandler,但它似乎只发送函数内的信息。我的目标是将msg变量值修改为ncol(database())

这是一个最小的例子:

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

$(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'}))
          }
}); 

感谢您的任何建议!

UPDATE1:

当我生成这样的情节时:

$(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)
        })
      }
    })

我无法查看任何情节。为什么? (它没有JavaScript动态div脚本工作)

1 个答案:

答案 0 :(得分:1)

根据您的描述,我认为主要问题是您只需调用一次JavaScript函数。 div仅在开始时调用一次。

另一个问题是,您只是添加到目标div,因此除非您清除其子updateTargetDiv元素,否则它将继续增长。

我认为以下代码可以满足您的需求。它创建一次CustomMessageHandler,并在传入新值时调用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'})); } } 元素。

$DSPL
$HASP893 VOLUME(SPLZ00) 852
$HASP893 VOLUME(SPLZ00)  STATUS=DRAINING,AWAITING(JOBS),
$HASP893                 PERCENT=2
$HASP893 VOLUME(SPLZ01)  STATUS=ACTIVE,PERCENT=38
$HASP893 VOLUME(SPLZ02)  STATUS=ACTIVE,PERCENT=36
$HASP646 37.5371 PERCENT SPOOL UTILIZATION

视觉: enter image description here