[英]Shiny and JavaScript interaction with session$sendCustomMessage
[英]R Shiny - Setting input values with 'session$sendCustomMessage' inside a Shiny module
我的应用程序包含一个名为set value
的按钮。 我想用sendCustomMessage
和setInputValue
输入的值重置inp
到“HI”,每次set value
被点击。 我正在为sendCustomMessage
方法使用一个名为setInputVal
的包装函数。
如果我在对 setInputVal 的调用中为输入 id 指定命名空间前缀,但如果我省略它,则不会按预期重置inp
的值。 所以setInputVal(session, ns('inp'), 'hi')
有效但setInputVal(session, 'inp', 'hi')
没有。
为什么我需要在这里指定命名空间前缀? 我的想法是session$sendCustomMessage
中的session$
位暗示消息正在访问模块的会话,因此不需要命名空间前缀(类似于我们在模块的服务器函数中如何使用input$inp
访问inp
的值而不是input[[ns('inp')]]
)。
为什么当我们在模块服务器中使用update*
函数(如updateSelectInput
)时,我们不需要指定 ns 前缀? (我在 UI 中包含了一个selectInput
并在服务器中包含了一个 observeEvent 以演示updateSelectInput
。)当我查看 updateSelectInput 的代码时,我看到它也使用session$sendInputMessage(inputId, message)
并且似乎没有附加任何时候 inputId 参数的 ns 前缀。
library(shiny)
setInputVal <- function(session, inputId, value) {
session$sendCustomMessage(
type = 'setInputVal',
message = list(
id = inputId, value = value)
)
}
# module UI ---------------------------------------------------------------
modUI <- function(id) {
ns = NS(id)
tagList(
tags$head(tags$script("Shiny.addCustomMessageHandler('setInputVal', function(data) {
Shiny.setInputValue(data.id, data.value);
});")),
# selectInput(ns('letter'), 'letter', letters),
actionButton(ns('set'), 'set value')
)
}
# module server -----------------------------------------------------------
modServer <- function(input, output, session) {
ns = session$ns
observeEvent(input$set, setInputVal(session, 'inp', value = 'hi'))
observe(print(input$inp))
# observeEvent(input$set, {
#
# updateSelectInput(session, 'letter', selected = 'u')
#
# print(input$letter)
# })
}
# main UI -----------------------------------------------------------------
ui <- fluidPage(modUI('hi'))
# main server -------------------------------------------------------------
server <- function(input, output, session) {
callModule(modServer, 'hi')
}
# Run app
shinyApp(ui, server)
使用sendCustomMessage()
您只是发送一个要在 JavaScript 中处理的 JSON 对象。 当您在 JS 中调用Shiny.setInputValue()
时,您已经丢失了有关会话的所有信息:仅保留消息数据。 在这种情况下,该消息恰好包含一个无作用域的输入 id,这意味着您实际上是在为全局"inp"
输入设置值。 因为自定义消息实际上可以做任何事情,所以会话无法对其进行修改。
但是,当您使用sendInputMessage()
,上下文是不同的:现在会话知道有一个inputId
并且它应该是范围的,它会自动执行; 看到这里。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.