我在 R Shiny 应用程序中将变量从模块返回到服务器时遇到了令人惊讶的困难。在模块中,我想在观察到按下按钮时返回一个值,因此我将return()语句包装在observeEvent(). 但是,没有返回所需的值,整个observeEvent()块似乎是。
我试图创建一个最小的工作示例,概述以下问题:
# ui.R
fluidPage(
input_module_ui("input"),
actionButton("print_input_button",
label = "Print Input")
)
Run Code Online (Sandbox Code Playgroud)
# server.R
function(input, output, session) {
# Calling input module.
input_module_return <- callModule(input_module, "input")
observeEvent(input$print_input_button, {
print(input_module_return)
})
}
Run Code Online (Sandbox Code Playgroud)
# global.R
source("modules/input.R")
Run Code Online (Sandbox Code Playgroud)
# input.R
input_module_ui <- function(id) {
ns <- NS(id)
tagList(
textInput(ns("text_input"),
label = h2("Input Text:")),
actionButton(ns("submit_input"),
label = "Submit Input")
)
}
input_module <- function(input, output, session) {
print("I should only print once")
observeEvent(input$submit_input, {
print("Return input")
return(input$text_input)
})
}
Run Code Online (Sandbox Code Playgroud)
在测试这个应用程序时,我在文本输入框中输入了“test”并提交了我的输入。但是,当我尝试打印我的输入时,并没有像我期望的那样打印“test”,而是打印了以下内容:
<Observer>
Public:
.autoDestroy: TRUE
.autoDestroyHandle: function ()
clone: function (deep = FALSE)
.createContext: function ()
.ctx: environment
destroy: function ()
.destroyed: FALSE
.domain: session_proxy
.execCount: 3
.func: function ()
initialize: function (observerFunc, label, suspended = FALSE, priority = 0,
.invalidateCallbacks: list
.label: observeEvent(input$submit_input)
.onDomainEnded: function ()
onInvalidate: function (callback)
.onResume: function ()
.prevId: 1896
.priority: 0
resume: function ()
run: function ()
self: Observer, R6
setAutoDestroy: function (autoDestroy)
setPriority: function (priority = 0)
suspend: function ()
.suspended: FALSE
Run Code Online (Sandbox Code Playgroud)
我相信这对应于中的最后一个块input.R:
observeEvent(input$submit_input, {
print("Return input")
return(input$text_input)
})
Run Code Online (Sandbox Code Playgroud)
我怎样才能让这个应用程序按预期工作并input$text_input在input$submit_input观察到时返回?
你已经很接近让这个工作了。闪亮模块的技巧是将变量传入和传出它们需要将变量作为反应值传递。我对您的代码进行了两个小的更改,以获得我认为您希望看到的内容。
首先是input$text_input从服务器模块返回一个反应版本(而不是从观察者本身,它应该告诉应用程序你想要发生什么):
input_module <- function(input, output, session) {
print("I should only print once")
observeEvent(input$submit_input, {
print("Return input")
})
return(reactive({input$text_input}))
}
Run Code Online (Sandbox Code Playgroud)
第二个变化是现在的输出input_module是反应性的。如果您想要值而不是函数内容,则需要使用(). 因此,在您的服务器功能中:
server <- function(input, output, session) {
# Calling input module.
input_module_return <- callModule(input_module, "input")
observeEvent(input$print_input_button, {
print(input_module_return())
})
}
Run Code Online (Sandbox Code Playgroud)
输出:
Listening on http://127.0.0.1:6796
[1] "I should only print once"
[1] "Return input"
[1] "test"
Run Code Online (Sandbox Code Playgroud)