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

Shiny DT嵌入selectInput并保存选项值实现多用户同步

解决Shiny DT嵌入选择框后保存选项值的问题

核心思路:不直接把selectInput的HTML代码存入.rds文件,而是存储选项的实际值(A/B/C);渲染DT时再根据数据里的值生成带选中状态的选择框,同时通过JavaScript监听选择变化,把选中值传回后端更新数据,实现多用户同步。

1. 初始化数据与实时读取

先确保初始数据存储的是选项值而非HTML,用reactiveFileReader监听.rds文件变化,自动同步多用户的界面数据:

server <- function(input, output, session) {
  # 第一次运行时初始化数据文件
  if (!file.exists("paper_data.rds")) {
    initial_data <- data.frame(
      论文标题 = c("实验室论文1", "实验室论文2"),
      评审状态 = c("A", "B"),  # 存实际选项值
      stringsAsFactors = FALSE
    )
    saveRDS(initial_data, "paper_data.rds")
  }

  # 实时读取数据,每2秒检查一次文件变化
  data_r <- reactiveFileReader(
    intervalMillis = 2000,
    session = session,
    filePath = "paper_data.rds",
    readFunc = readRDS
  )
}

2. 渲染带选中状态的选择框到DT

在renderDT中,将目标列转换为带选中值的selectInput HTML,确保渲染时显示正确的选中状态:

output$paper_table <- renderDT({
  data <- data_r()
  # 为每行生成带选中值的选择框
  data$评审状态 <- mapply(function(val, row_id) {
    as.character(selectInput(
      inputId = paste0("status_", row_id),  # 唯一ID,绑定行号
      label = NULL,
      choices = c("A", "B", "C"),
      selected = val,  # 对应数据里的实际值
      width = "100px"
    ))
  }, data$评审状态, rownames(data))
  
  datatable(
    data,
    escape = FALSE,  # 不转义HTML,让选择框正常显示
    selection = "none",
    options = list(dom = "t", ordering = FALSE)
  )
})

3. 用JS监听选择变化,传递数据到后端

在UI中添加JavaScript代码,监听所有选择框的变化事件,把选中值和对应行号传回Shiny:

ui <- fluidPage(
  DTOutput("paper_table"),
  tags$script(HTML('
    // 监听所有select元素的change事件
    $(document).on("change", "select", function() {
      var inputId = $(this).attr("id");
      var rowId = inputId.split("_")[1];  // 从ID提取行号
      var selectedVal = $(this).val();
      // 把数据发送到Shiny后端
      Shiny.setInputValue("status_update", {
        row: rowId,
        value: selectedVal
      });
    })
  '))
)

4. 后端接收更新,保存到.rds

在server中监听前端传来的更新信号,修改数据并写入.rds文件:

observeEvent(input$status_update, {
  req(input$status_update)
  current_data <- data_r()
  # 定位到对应行,更新选项值
  row_idx <- as.integer(input$status_update$row)
  current_data$评审状态[row_idx] <- input$status_update$value
  # 保存更新后的数据
  saveRDS(current_data, "paper_data.rds")
})

关键说明

  • 全程保证.rds文件存储的是A/B/C这类实际值,HTML仅用于DT的前端渲染
  • reactiveFileReader会自动检测文件变化,其他用户打开应用时能实时看到最新的选择状态
  • 每个选择框的唯一ID绑定行号,确保后端能精准定位到要更新的行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:59:49