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

如何在R Shiny的removeUI函数中正确设置选择器实现单表删除?

解决R Shiny表格删除问题的修正方案

核心问题分析

  1. 删除逻辑错误:原代码中removeUI使用selector = NULL会删除所有元素,需改为目标表格对应的div ID选择器。
  2. 观察者结构冗余:删除逻辑的观察者被嵌套在添加表格的观察者中,导致重复触发。
  3. 初始表格渲染缺失:原代码未定义初始表格的renderRHandsontable输出。
  4. 表格命名连续性:删除后需确保剩余表格的列名和选择器选项保持连续编号。

关键修复点

  • 精准删除目标表格:通过选择器paste0("#", divID)定位要删除的表格容器div,而非全局删除。
  • 重构观察者结构:将删除逻辑、表格命名更新的观察者独立出来,避免重复创建。
  • 保持命名连续性:每次uiTbl变化时,重新为剩余表格分配连续的列名和选择器选项。
  • 修复初始表格渲染:添加初始表格的renderRHandsontable输出。

修正后的完整代码

library(rhandsontable)
library(shiny)

data1 <- data.frame(row.names = c("A","B","C","Sum"),"Col 1"=c(1,1,0,2),check.names=FALSE)

ui <- fluidPage(br(),
                actionButton("addTbl","Add table"), br(), br(),
                tags$div(id = "placeholder",        
                         tags$div(
                           style = "display: inline-block; margin-right: 10px;", 
                           rHandsontableOutput("hottable1")
                         )
                ),br(),
                selectizeInput(inputId = "select_deletion",
                               label = "Select deletion",
                               choices = NULL,
                               selected = NULL,
                               multiple = TRUE
                )
)

server <- function(input, output, session) {
  uiTbl <- reactiveValues(div_01_tbl = data1)
  
  # 渲染初始表格
  output$hottable1 <- renderRHandsontable({
    req(uiTbl$div_01_tbl)
    rhandsontable(uiTbl$div_01_tbl, useTypes = TRUE)
  })
  
  # 更新初始表格数据
  observeEvent(input$hottable1, {
    uiTbl$div_01_tbl <- hot_to_r(input$hottable1)
  })
  
  # 添加新表格
  observeEvent(input$addTbl, {
    divID <- paste0("div_", sprintf("%02d", input$addTbl + 1))
    dtID <- paste0(divID, "_DT")
    uiTbl_key <- paste0(divID, "_tbl")
    
    # 避免重复添加
    if (!exists(uiTbl_key, envir = uiTbl)) {
      uiTbl[[uiTbl_key]] <- data1
      
      insertUI(
        selector = "#placeholder",
        ui = tags$div(
          id = divID,
          style = "display: inline-block; margin-right: 10px;",
          rHandsontableOutput(dtID)
        )
      )
      
      # 渲染新表格
      output[[dtID]] <- renderRHandsontable({
        req(uiTbl[[uiTbl_key]])
        rhandsontable(uiTbl[[uiTbl_key]], useTypes = TRUE)
      })
      
      # 更新新表格数据
      observeEvent(input[[dtID]], {
        uiTbl[[uiTbl_key]] <- hot_to_r(input[[dtID]])
      })
    }
  })
  
  # 动态更新表格列名和选择器选项
  observe({
    tables_list <- reactiveValuesToList(uiTbl)
    # 按div ID排序表格
    tables_list <- tables_list[order(names(tables_list))]
    # 过滤空值
    tables_list <- tables_list[!sapply(tables_list, is.null)]
    
    # 分配连续列名
    table_names <- paste("Col", seq_along(tables_list))
    for (i in seq_along(tables_list)) {
      uiTbl_key <- names(tables_list)[i]
      if (!is.null(uiTbl[[uiTbl_key]])) {
        names(uiTbl[[uiTbl_key]]) <- table_names[i]
      }
    }
    
    # 更新选择器选项
    freezeReactiveValue(input, "select_deletion")
    updateSelectizeInput(session, 
                        inputId = "select_deletion", 
                        choices = table_names, 
                        selected = NULL)
  })
  
  # 处理表格删除
  observeEvent(input$select_deletion, {
    req(input$select_deletion)
    
    tables_list <- reactiveValuesToList(uiTbl)
    tables_list <- tables_list[order(names(tables_list))]
    tables_list <- tables_list[!sapply(tables_list, is.null)]
    table_names <- paste("Col", seq_along(tables_list))
    
    for (selected_name in input$select_deletion) {
      idx <- which(table_names == selected_name)
      if (length(idx) > 0) {
        uiTbl_key <- names(tables_list)[idx]
        divID <- gsub("_tbl$", "", uiTbl_key)
        
        # 删除目标表格UI
        removeUI(selector = paste0("#", divID))
        # 删除对应数据
        uiTbl[[uiTbl_key]] <- NULL
      }
    }
    
    # 清空选择器选中状态
    freezeReactiveValue(input, "select_deletion")
    updateSelectizeInput(session, 
                        inputId = "select_deletion", 
                        selected = NULL)
  }, ignoreNULL = TRUE)
}

shinyApp(ui, server)

功能说明

  • 添加表格:点击"Add table"按钮可新增左对齐的表格,表格间有间距。
  • 编辑表格:所有表格支持手动编辑,数据实时保存。
  • 删除表格:通过下拉选择器选中一个或多个表格,对应表格会被精准删除,剩余表格自动保持连续命名和左对齐排列。

内容的提问来源于stack exchange,提问作者Village.Idyot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:41:21