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

如何用Shiny书签功能保存DT包Search Builder扩展的自定义参数?

实现Shiny书签与DT Search Builder参数的保存与恢复

要把Shiny的书签功能和DT的Search Builder扩展结合,保存用户自定义的过滤参数及其他应用状态,可通过以下步骤实现:

核心思路

利用Shiny的onBookmark和onRestore钩子,配合DT的JavaScript API,手动捕获并恢复Search Builder的过滤状态,同时将其他输入控件的状态一同纳入书签体系。

完整可运行示例

library(shiny)
library(DT)

enableBookmarking("url")

ui <- function(request) {
  fluidPage(
    titlePanel("DT Search Builder + Shiny 书签示例"),
    sidebarLayout(
      sidebarPanel(
        sliderInput("num_filter", "数值范围过滤", min = 1, max = 100, value = c(20, 80)),
        bookmarkButton()
      ),
      mainPanel(
        DTOutput("data_table"),
        tags$script(HTML("
          // 获取Search Builder状态并发送给Shiny后端
          function getSearchBuilderState(tableId) {
            const table = $('#' + tableId).DataTable();
            return table.searchBuilder.getDetails();
          }
          
          // 恢复Search Builder状态
          function setSearchBuilderState(tableId, state) {
            const table = $('#' + tableId).DataTable();
            table.searchBuilder.rebuild(state);
          }
          
          // 监听Shiny的恢复消息
          Shiny.addCustomMessageHandler('restoreSearchBuilder', function(message) {
            setSearchBuilderState(message.tableId, message.state);
          });
        "))
      )
    )
  )
}

server <- function(input, output, session) {
  # 生成示例数据
  sample_data <- reactive({
    data.frame(
      ID = 1:100,
      Name = paste0("Item_", 1:100),
      Value = sample(1:100, 100, replace = TRUE),
      Category = sample(c("A", "B", "C"), 100, replace = TRUE)
    )
  })
  
  # 渲染带Search Builder的DT
  output$data_table <- renderDT({
    datatable(
      sample_data(),
      extensions = "SearchBuilder",
      options = list(
        searchBuilder = TRUE,
        pageLength = 10
      )
    )
  })
  
  # 书签保存时捕获状态
  onBookmark(function(state) {
    # 获取Search Builder状态
    sb_state <- session$sendCustomMessageSync("getSearchBuilder", list(tableId = "data_table"))
    # 将状态存入书签
    state$values$search_builder_state <- sb_state
    # 其他输入控件状态会自动保存,这里也可手动添加额外状态
  })
  
  # 书签恢复时应用状态
  onRestore(function(state) {
    # 恢复Search Builder状态
    if (!is.null(state$values$search_builder_state)) {
      session$sendCustomMessage("restoreSearchBuilder", list(
        tableId = "data_table",
        state = state$values$search_builder_state
      ))
    }
    # 其他输入控件状态会自动恢复,无需额外处理
  })
  
  # 注册获取Search Builder状态的消息处理器
  session$registerDataObj("getSearchBuilder", function(data, req) {
    sb_state <- getSearchBuilderState(data$tableId)
    jsonlite::toJSON(sb_state, auto_unbox = TRUE)
  })
}

shinyApp(ui, server)

关键部分解释

  1. 启用书签功能:通过enableBookmarking("url")开启基于URL的书签,状态会编码到URL中。
  2. 前端JS逻辑:
    • getSearchBuilderState:调用DT的searchBuilder.getDetails()获取当前过滤规则的结构化数据。
    • setSearchBuilderState:调用searchBuilder.rebuild()将保存的状态重新应用到表格。
  3. 书签钩子:
    • onBookmark:在生成书签时,同步调用前端JS获取Search Builder状态,并存入书签的values对象。
    • onRestore:加载书签时,将保存的状态通过自定义消息发送给前端,触发状态恢复。
  4. 自动与手动状态处理:Shiny会自动保存/恢复标准输入控件(如示例中的滑块)的状态,Search Builder属于DT扩展,需手动处理。

内容的提问来源于stack exchange,提问作者A-A-ron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:57:14