表格单元格内SelectInput在依赖输入变更或重触actionButton后无法读取input$ID值
问题根源
- 核心问题1:将
DT::renderDataTable嵌套在observeEvent(input$go)中属于Shiny开发反模式,每次点击Go按钮都会重新生成render绑定,旧DOM元素和Shiny输入绑定未被正确清理,重复ID的输入组件出现绑定冲突,导致input$student_row*无法被正确识别 - 核心问题2:未在UI中初始化
shinyjs,导致显隐逻辑失效 - 核心问题3:缺失必要的依赖包声明,直接运行会报错
- 核心问题4:班级切换逻辑和Go按钮触发逻辑未对齐,出现状态不一致
修复后的完整可运行代码
master_table <- data.frame("class_col" = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C"), "all_student"=c("CA1", "CA2", "CA3", "CA4", "CA5", "CB1", "CB2", "CB3", "CB4", "CB5", "CC1", "CC2", "CC3", "CC4", "CC5")) # 加载所有依赖包 library(shiny) library(shinyjs) library(shinyWidgets) library(DT) library(data.table) ui <- fluidPage( shinyjs::useShinyjs(), # 初始化shinyjs fluidRow( selectInput("class_input", label = "Class", choices= sort(c("Select Class"='', unique(master_table$class_col))), selected=NULL), shinyjs::hidden(tags$div(id="alert", tags$h5("* Please Select Class ", style = "color:red"))), actionBttn(inputId = 'go', label='Go!'), shinyjs::hidden(tags$div(id='hidden_table', DT::dataTableOutput('student_select_table'))), textOutput("text_output_for_selected_Student_at_Row1") ) ) server <- function(input, output, session) { # 存储点击Go后确认的选中班级 selected_class <- reactiveVal("") # 监听Go按钮点击 observeEvent(input$go, { if(nchar(input$class_input)<1){ shinyjs::showElement("alert") shinyjs::hideElement("hidden_table") selected_class("") } else { shinyjs::hideElement("alert") shinyjs::showElement("hidden_table") selected_class(input$class_input) } }) # 根据选中的班级生成带下拉框的表格数据 student_reactive <- reactive({ req(selected_class()) student_table = data.table('student_input_col' = 1:5) cur_choices = sort(c("Select Student"='', master_table$all_student[master_table$class_col == selected_class()])) for (i in 1:nrow(student_table)){ student_table$student_input_col[i] <- as.character(selectInput(inputId = paste0("student_row", i), label=NULL, choices = cur_choices)) } return(student_table) }) # 独立渲染DT表格,不嵌套在observe中 output$student_select_table <- DT::renderDataTable({ req(student_reactive()) datatable(student_reactive(), class= "cell-border", rownames = FALSE, width = "80%",escape = FALSE, selection = "single", options = list(dom='t', paging=FALSE, ordering=FALSE, info=FALSE, rowCallback = JS("function(r,d) {$(r).attr('height', '40px')}"), preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'), drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')) ) }) output$text_output_for_selected_Student_at_Row1 <- renderText(paste0("Text for Student at Row1 = ", input$student_row1)) } runApp(shinyApp(ui = ui, server = server))
修复效果
现在切换班级后点击Go按钮重新生成表格,或是多次点击Go按钮,下拉框的选中值都可以被正常读取,文本输出会实时同步更新。
内容的提问来源于stack exchange,提问作者borderline_coder
相关产品推荐
相关产品推荐

