You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自动恢复本地最后一个Shiny书签:解决绘图更新与覆盖问题

解决方案

1. 解决绘图持续更新的主要问题

原代码通过JS跳转实现书签恢复,会导致应用重新加载并重复触发恢复逻辑,进而引发绘图的持续更新。改为在服务器初始化时直接调用session$restoreState()加载最后一个书签,无需页面跳转,从根源避免重复渲染。

2. 解决书签覆盖的次要问题

每次保存书签前,删除shiny_bookmarks目录下的所有旧书签文件,确保只保留最新的一个,避免文件堆积。

修改后的完整代码

library("shiny")
library("shinyjs")
library("tidyverse")

## module to do something with the data
shinyModuleUserInterface <- function(id, label) {
  ns <- NS(id) 
  tagList(
    titlePanel("Track of individual"),
    selectInput(inputId = ns("indv"), label = "Select indivdual", 
                choices = c("A","B","C"), selected="A"),
    plotOutput(ns("plot"))
  )
}

shinyModule <- function(input, output, session) { 
  ns <- session$ns 
  dataTrk <- data.frame(indv=rep(c("A","B","C"), each=4), 
                        x=c(1,4,2,6,9,5,3,8,9,4,3,7),
                        y=c(7,5,9,3,1,2,6,4,9,5,1,6))
  output$plot <- renderPlot({
    plot(y~x, dataTrk[dataTrk$indv==input$indv,], type="l")
  })
}

## function to get the last bookmark saved
get_last_bookmark <- function(){
  list.files(path = 'shiny_bookmarks/') %>% 
    map_df(., ~paste0('shiny_bookmarks/', .x) %>%
             file.info) %>%
    slice_max(atime) %>%
    rownames()
}
get_last_bookmark <- possibly(get_last_bookmark, otherwise = '') #avoid empty folder error

## main app code
ui <- function(request) { 
  fluidPage(
    useShinyjs(),
    shinyModuleUserInterface("shinyModule"),
    bookmarkButton()
  )
}

server <- function(input, output, session) {
  
  callModule(shinyModule,"shinyModule")
  
  onBookmarked(function(state){
    # 保存新书签前,删除所有旧书签文件
    old_bookmarks <- list.files(path = 'shiny_bookmarks/', full.names = TRUE)
    file.remove(old_bookmarks[old_bookmarks != state$dir])
    # 关闭默认弹窗,改用简洁通知
    showNotification("书签已保存", type = "message", duration = 1)
  })
  
  # 服务器启动时直接恢复最后一个书签
  observe({
    req(get_last_bookmark() != "")
    session$restoreState(get_last_bookmark())
  }, once = TRUE)
}

shinyApp(ui, server, enableBookmarking="server")

关键说明

  • 绘图持续更新问题解决:通过session$restoreState()在服务器端直接加载书签状态,无需页面跳转,避免了重复触发响应式计算,绘图只会在恢复完成后渲染一次。
  • 书签覆盖问题解决:在onBookmarked回调中,删除除当前新书签外的所有旧文件,确保shiny_bookmarks目录下始终只有一个最新书签,避免文件堆积。

内容的提问来源于stack exchange,提问作者AnneScharf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:55:20