繁体   English   中英

R Shiny - 在 Shiny 模块中使用“session$sendCustomMessage”设置输入值

[英]R Shiny - Setting input values with 'session$sendCustomMessage' inside a Shiny module

我的应用程序包含一个名为set value的按钮。 我想用sendCustomMessagesetInputValue输入的值重置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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM