我正在尝试创建一个 Shiny
应用程序使用 golem
首次。 golem
结构 Shiny
带有模块的应用程序有助于保持大型 Shiny
应用程序模块化。但是,默认情况下,模块不会相互通信。我想跨模块共享数据。根据 golem
文档, R6
objects are a useful way to share data across modules .
然而,在 example provided in the golem
documentation , 不清楚在哪里放置 R6
发电机。根据Appsilon , R6
生成器进入单独的.R
文件(例如,logger_manager.R
),并在 global.R
中调用电话从类中构造一个新对象:logger_manager = LoggerManager$new()
.但是,没有global.R
golem
中的文件基于Shiny
应用程序。
下面是我的 golem
的一个最小示例基于Shiny
应用程序。我尝试遵循 example provided in the golem
documentation 中的结构,但它似乎没有跨模块共享数据:app_ui.R
:
app_ui <- function(request) {
tagList(
# Leave this function for adding external resources
golem_add_external_resources(),
# List the first level UI elements here
fluidPage(
mod_a_ui("a_ui_1"),
mod_b_ui("b_ui_1")
)
)
}
golem_add_external_resources <- function(){
add_resource_path(
'www', app_sys('app/www')
)
tags$head(
favicon(),
bundle_resources(
path = app_sys('app/www'),
app_title = 'Test'
),
# Add here other external resources
# for example, you can add shinyalert::useShinyalert()
shinyjs::useShinyjs()
)
}
app_server.R
:app_server <- function( input, output, session ) {
# Generate R6 Class
QuestionnaireResponses <- R6Class(
classname = "QuestionnaireResponses",
public = list(
resp_id = NULL,
timezone = NULL,
timestamp = NULL,
gender = NULL,
)
)
# Create new object to share data across modules using the R6 Class
questionnaire_responses <- QuestionnaireResponses$new()
# List the first level callModules here
callModule(mod_a_server, "a_ui_1", questionnaire_responses)
callModule(mod_b_server, "b_ui_1", questionnaire_responses)
}
mod_a.R
:mod_a_ui <- function(id){
ns <- NS(id)
tagList(
radioButtons(inputId = "gender",
label = "What is your sex?",
choices = c("Male" = 1,
"Female" = 2),
selected = character(0))
)
}
mod_a_server <- function(input, output, session, questionnaire_responses){
ns <- session$ns
# Add time start to the output vector
timestamp <- format(Sys.time(), "%Y-%m-%d %H:%M:%OS6")
timezone <- Sys.timezone()
# Generate a survey-specific ID number
resp_id <- paste0(sample(c(letters, LETTERS, 0:9), 10), collapse = "")
# Assign values to R6 object
questionnaire_responses$resp_id <- resp_id
questionnaire_responses$timezone <- timezone
questionnaire_responses$timestamp <- timestamp
questionnaire_responses$gender <- input.gender
}
mod_b.R
:mod_b_ui <- function(id){
ns <- NS(id)
tagList(
print("questionnaire_responses$resp_id")
)
}
mod_b_server <- function(input, output, session, questionnaire_responses){
ns <- session$ns
}
但是,数据不能跨模块共享,因为当我尝试打印 resp_id
时在模块 B(在模块 A 中生成)中,我收到以下错误:An error has occurred!
object 'questionnaire_responses' not found
最佳答案
所以这里的问题是您正在尝试打印对象 来自 UI 功能 当您的 R6 对象通过 到服务器函数 .
换句话说,您正试图在 mod_b_ui
中进行打印。函数,当 R6 对象被传递给 mod_b_server
功能。
对于您的原始问题,您可以在标准文件中创建 R6 类,如 https://github.com/ColinFay/golemexamples/blob/master/golemR6/R/R6.R
请注意,您的数据对象是 无 react 并且当您在模块 A 中更改时不会重新打印 - 这是您可以使用 {gargoyle}
的地方例如:
请看 https://github.com/ColinFay/golemexamples/tree/master/golemR6一个完整的工作示例。
PS:您的模块中缺少 ns() :)
科林
关于r - 如何在 golem Shiny 应用程序中包含 R6 对象以跨模块共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67075905/