R Shiny书签恢复时如何实现依赖型输入控件仅更新一次
解决Shiny书签恢复时input2重复更新的问题
当通过书签链接恢复页面时,现有逻辑会先恢复input1的选中值,触发依赖input1的观察者更新input2选项;随后onRestored回调又设置input2的选中值,导致input2被两次更新,触发重复的耗时操作。
解决方案
核心思路是在恢复阶段跳过自动更新input2的观察者,转而在onRestored中一次性完成input2的选项更新与选中值设置,避免重复操作。利用session$isRestoring()判断当前是否处于恢复状态,控制观察者的执行时机。
修改后的完整代码
df <- structure(list(Input1 = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C"), Input2 = c(1L, 2L, 3L, 5L, 7L, 2L, 4L, 6L, 7L, 8L, 1L, 4L, 5L, 6L, 7L)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -15L), groups = structure(list( Input1 = c("A", "B", "C"), .rows = structure(list(1:5, 6:10, 11:15), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))), row.names = c(NA, -3L), .drop = TRUE, class = c("tbl_df", "tbl", "data.frame"))) shinyApp( ui = function(request) {fluidPage( selectInput("input1", "input1", choices = unique(df$Input1)), selectInput("input2", "input2", choices = NA) )}, server = function(input, output, session){ # 仅在非恢复阶段,根据input1更新input2选项 observe({ req(input$input1) if (!session$isRestoring()) { tmp_input2 <- df %>% filter(Input1 == input$input1) %>% pull(Input2) updateSelectInput(session, "input2", choices = tmp_input2) } }) # 自动生成书签 observe({ session$doBookmark() }) onBookmarked(function(url) { updateQueryString(url) }) # 恢复时一次性设置input2的选项与选中值 onRestored(function(state) { req(state$input$input1) tmp_input2 <- df %>% filter(Input1 == state$input$input1) %>% pull(Input2) updateSelectInput( session, "input2", choices = tmp_input2, selected = state$input$input2 ) }) # 测试用:打印input2的变化 observe({ print(input$input2) }) },enableBookmarking = "url")
代码说明
session$isRestoring():返回当前是否处于书签恢复流程中,恢复阶段为TRUE,完成后转为FALSE。利用这个条件让依赖input1的观察者在恢复时跳过执行。onRestored回调:直接从书签状态中获取input1的值,生成对应input2的选项,同时设置选中值,一次性完成input2的初始化,避免重复更新。- 正常操作时,切换
input1仍会触发观察者更新input2选项,不影响原有功能。
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

