itp*_*sen 7 module r shiny r6 golem
我\xe2\x80\x99m第一次尝试创建一个Shiny应用程序。使用模块构建应用程序,以帮助保持大型应用程序的模块化。但是,默认情况下,模块之间不\xe2\x80\x99 相互通信。I\xe2\x80\x99d 喜欢跨模块共享数据。根据文档,对象是跨模块共享数据的有用方法。golemgolemShinyShinygolemR6
然而,在文档中提供的示例golem中,并不清楚将R6生成器放在哪里。根据Appsilon 的说法,R6生成器进入一个单独的.R文件(例如logger_manager.R),并进行调用global.R以从类构造一个新对象:logger_manager = LoggerManager$new()。但是,基于 的应用程序中没有global.R文件。golemShiny
golem下面是我的应用程序的一个最小示例Shiny。我尝试遵循文档中提供的示例golem中的结构,但它似乎没有跨模块共享数据:
app_ui.R:
app_ui <- function(request) {\n tagList(\n # Leave this function for adding external resources\n golem_add_external_resources(),\n \n # List the first level UI elements here \n fluidPage(\n mod_a_ui("a_ui_1"),\n mod_b_ui("b_ui_1")\n )\n )\n}\n\ngolem_add_external_resources <- function(){\n \n add_resource_path(\n \'www\', app_sys(\'app/www\')\n )\n \n tags$head(\n favicon(),\n bundle_resources(\n path = app_sys(\'app/www\'),\n app_title = \'Test\'\n ),\n # Add here other external resources\n # for example, you can add shinyalert::useShinyalert()\n shinyjs::useShinyjs()\n )\n}\nRun Code Online (Sandbox Code Playgroud)\napp_server.R:
app_server <- function( input, output, session ) {\n \n # Generate R6 Class\n QuestionnaireResponses <- R6Class(\n classname = "QuestionnaireResponses",\n public = list(\n resp_id = NULL,\n timezone = NULL,\n timestamp = NULL,\n gender = NULL,\n )\n )\n \n # Create new object to share data across modules using the R6 Class\n questionnaire_responses <- QuestionnaireResponses$new()\n \n # List the first level callModules here\n callModule(mod_a_server, "a_ui_1", questionnaire_responses)\n callModule(mod_b_server, "b_ui_1", questionnaire_responses)\n}\nRun Code Online (Sandbox Code Playgroud)\nmod_a.R:
mod_a_ui <- function(id){\n ns <- NS(id)\n \n tagList(\n radioButtons(inputId = "gender",\n label = "What is your sex?",\n choices = c("Male" = 1,\n "Female" = 2),\n selected = character(0))\n)\n}\n\nmod_a_server <- function(input, output, session, questionnaire_responses){\n ns <- session$ns\n \n # Add time start to the output vector\n timestamp <- format(Sys.time(), "%Y-%m-%d %H:%M:%OS6")\n timezone <- Sys.timezone()\n \n # Generate a survey-specific ID number\n resp_id <- paste0(sample(c(letters, LETTERS, 0:9), 10), collapse = "")\n \n # Assign values to R6 object\n questionnaire_responses$resp_id <- resp_id\n questionnaire_responses$timezone <- timezone\n questionnaire_responses$timestamp <- timestamp\n questionnaire_responses$gender <- input.gender\n}\nRun Code Online (Sandbox Code Playgroud)\nmod_b.R:
mod_b_ui <- function(id){\n ns <- NS(id)\n tagList(\n print("questionnaire_responses$resp_id")\n )\n}\n\nmod_b_server <- function(input, output, session, questionnaire_responses){\n ns <- session$ns\n }\nRun Code Online (Sandbox Code Playgroud)\n但是,数据不得跨模块共享,因为当我尝试resp_id在模块 B(在模块 A 中生成)中打印时,我收到以下错误:
An error has occurred!\nobject \'questionnaire_responses\' not found\nRun Code Online (Sandbox Code Playgroud)\n
因此,这里的问题是,当 R6 对象传递到服务器函数时,您试图从 UI 函数打印对象。
\nmod_b_ui换句话说,当 R6 对象传递给函数时,您尝试在函数中进行打印mod_b_server。
对于您原来的问题,您可以在标准文件中创建 R6 类,如https://github.com/ColinFay/golemexamples/blob/master/golemR6/R/R6.R
\n请注意,尽管您的数据对象不是反应性的,并且当您在模块 A \xe2\x80\x94 中更改时不会重新打印,但您可以在此处使用,{gargoyle}例如:
请参阅https://github.com/ColinFay/golemexamples/tree/master/golemR6了解完整的工作示例。
\nPS:您的模块中缺少 ns() :)
\n科林
\n