如何在Shiny应用中从服务器端向UI传递动态变量?
如何在Shiny应用中从服务器端向UI传递动态变量?
当然可以实现!你想用Shiny的自定义消息机制来传递服务器变量到前端JS的思路完全正确,只是之前的代码在自定义消息处理器的写法和变量使用上有几个小问题。我来帮你修正并解释清楚两种可行的实现方式~
方式一:提前将服务器变量传递到前端,点击时直接使用
这种方式适合变量不会频繁变化的场景,应用启动时就把服务器的变量传到前端存起来,点击段落时直接显示这个预存的值:
library(shiny) ui <- fluidPage( tags$p(id = 'g', class = 'newClass', 'This is a paragraph'), tags$p(id = "demo"), tags$script(HTML( "// 定义全局变量存储服务器传来的日期 var serverDate = ''; // 设置自定义消息处理器,接收服务器消息并赋值给全局变量 Shiny.addCustomMessageHandler('sendDate', function(message) { serverDate = message; }); // 给段落绑定点击事件,点击时展示预存的服务器日期 document.getElementById('g').onclick = function() { document.getElementById('demo').innerHTML = serverDate; }; " )) ) server <- function(input, output, session) { # 定义服务器端的变量 Var1 <- Sys.Date() # 应用启动时发送变量到前端 observe({ # 把日期转成字符串,方便前端直接显示 session$sendCustomMessage(type = 'sendDate', message = as.character(Var1)) }) } shinyApp(ui, server)
方式二:点击时触发服务器请求最新变量
如果你的Var1是动态变化的(比如需要每次点击都获取服务器的最新日期),可以用这种方式:点击段落时,前端主动向服务器请求变量,服务器返回后再显示:
library(shiny) ui <- fluidPage( tags$p(id = 'g', class = 'newClass', 'This is a paragraph'), tags$p(id = "demo"), tags$script(HTML( "// 点击段落时,给服务器发送请求信号 document.getElementById('g').onclick = function() { // 用随机数触发请求,确保每次点击都能触发服务器的observe Shiny.setInputValue('requestLatestDate', Math.random()); }; // 接收服务器返回的最新日期并展示 Shiny.addCustomMessageHandler('updateDemoText', function(message) { document.getElementById('demo').innerHTML = message; }); " )) ) server <- function(input, output, session) { # 监听前端的请求,返回最新的变量值 observeEvent(input$requestLatestDate, { # 这里可以是任何动态计算的变量,比如实时获取最新日期 Var1 <- Sys.Date() session$sendCustomMessage(type = 'updateDemoText', message = as.character(Var1)) }) } shinyApp(ui, server)
你之前尝试的问题点
你之前的代码主要有两个小错误:
- 自定义消息处理器语法错误:
Shiny.addCustomMessageHandler('bla',function(message) {return(message)};没有闭合括号,而且处理器的回调函数不是用来return值的,而是应该把收到的消息存到变量里。 - 变量赋值错误:你把
insertion_text直接设为处理器函数本身,而不是处理器收到的实际消息内容,所以点击时无法拿到正确的服务器变量。
备注:内容来源于stack exchange,提问作者Vinay Kumar
相关产品推荐
相关产品推荐

