使用withr::with_options设置shiny.maxRequestSize为何未生效?
问题根源
你遇到的问题核心在于 shinyApp() 只是创建一个Shiny应用对象,并不会直接启动应用。当你把shinyApp()放在withr::with_options的代码块里时,这个块只完成了「创建应用对象」的操作,而当你实际运行这个应用对象(比如在控制台执行返回的对象)时,with_options的临时选项设置已经失效了——因为那个代码块早就执行完毕,选项已经被重置回原来的值了。
而getOption("repos")能正常显示,是因为它读取的是R的全局默认仓库配置,这个配置在应用运行时依然存在,和with_options的临时上下文无关。
解决办法
有两种简单的方式可以让with_options的设置在Shiny应用运行期间生效:
方法1:用runApp()包裹应用对象,放在with_options块内
把shinyApp()创建的对象传给runApp(),并将整个runApp()调用放在with_options的上下文里。这样应用启动和运行的全程都会处于临时选项的作用域内:
library(shiny) ui <- fluidPage( verbatimTextOutput("option"), verbatimTextOutput("option2"), actionButton("go","go") ) server <- function(input, output, session) { output$option <- renderText({getOption("repos")}) output$option2 <- renderText({ getOption("shiny.maxRequestSize") }) } withr::with_options(list(shiny.maxRequestSize="find_me"), { shiny::runApp(shiny::shinyApp(ui, server)) })
方法2:在应用启动时通过session钩子设置选项(灵活控制方案)
如果你希望在应用内部控制选项,但又不想直接在server里硬编码,可以利用session$onSessionStarted钩子,在每个会话启动时临时设置选项。这种方式能保证会话级别的临时生效:
library(shiny) ui <- fluidPage( verbatimTextOutput("option"), verbatimTextOutput("option2"), actionButton("go","go") ) server <- function(input, output, session) { session$onSessionStarted(function() { withr::local_options(list(shiny.maxRequestSize="find_me")) }) output$option <- renderText({getOption("repos")}) output$option2 <- renderText({ getOption("shiny.maxRequestSize") }) } shiny::shinyApp(ui, server)
显然第一种方法更符合你想用withr::with_options的初衷,它能确保整个应用运行期间都处于临时选项的作用域内。
内容的提问来源于stack exchange,提问作者Vincent Guyader
相关产品推荐
相关产品推荐

