如何从磁盘加载reactiveValues且不破坏Shiny中的observer?
Shiny加载状态后Observer失效的解决办法
问题原因
你在load_app_state()里的r <- do.call(reactiveValues, state)操作,是创建了一个全新的局部reactiveValues对象,而原来的observer监听的是一开始定义的全局r对象。新对象和旧对象完全独立,既不会触发旧observer的响应,这个局部的r还会在函数执行结束后被销毁,等于白做。
解决方案
不要替换整个r对象,而是更新原有reactiveValues对象里的元素。只要操作的是同一个reactiveValues实例,修改其元素就会触发所有监听它的observer。
修改后的可运行代码
library(shiny) reactiveConsole(T) r <- reactiveValues() r$a <- 1 r$b <- 2 observe(cat("State:", r$a, r$b, "\n")) #> State: 1 2 savepath <- tempfile() save_app_state <- function() { saveRDS(reactiveValuesToList(r), savepath) } # 修正后的加载函数 load_app_state <- function() { state <- readRDS(savepath) # 遍历状态列表,逐个更新原对象的元素 for (name in names(state)) { r[[name]] <- state[[name]] } } save_app_state() r$b <- 0 #> State: 1 0 load_app_state() #> State: 1 2 (触发observer输出,符合预期)
复杂场景扩展
如果需要处理包含删除元素的状态恢复,可以先清空原有元素再添加新状态:
load_app_state <- function() { state <- readRDS(savepath) # 先清空原有所有元素 for (name in names(r)) { r[[name]] <- NULL } # 加载新状态的元素 for (name in names(state)) { r[[name]] <- state[[name]] } }
内容的提问来源于stack exchange,提问作者pietrodito
相关产品推荐
相关产品推荐

