如何在Shiny模块的modalDialog中动态生成并捕获用户输入?
问题根因
- 动态生成的
selectInput未添加模块命名空间:Shiny模块内所有自定义输入ID都需要通过session$ns()封装,否则模块的输入作用域无法匹配到对应的动态控件值 - JS回调配置错误:原代码给表格行添加了滑块输入专属类
shiny-input-slider-input,和下拉选择控件的类型不匹配,额外添加行ID/类的逻辑属于冗余代码,反而会干扰Shiny的输入绑定 - 绑定时机逻辑存在隐患:原JS代码未确保DT完全渲染完成后再执行绑定操作
修复方案
1. 动态生成控件时添加命名空间
在循环生成selectInput时,给inputId套上当前模块的命名空间:
for(i in seq_len(nrow(fieldmapping_table))) { fieldmapping_table[i,"DB.Field.Mapping"] <- as.character(selectInput( # 核心修改:封装模块命名空间 inputId = ns(glue::glue("fieldmap_select_{fieldmapping_table$File.Column[i]}")), label = NULL, choices = db_cols )) }
2. 简化DT的JS回调
删除冗余的行属性设置逻辑,保留核心的绑定/解绑代码即可:
DT::datatable(fieldmapping_table, escape = 2, selection = "none", filter = 'none', options = list( dom = 't' ), # 修改后的回调代码 callback = JS(" Shiny.unbindAll(table.table().node()); Shiny.bindAll(table.table().node()); ") )
验证方式
修改完成后,在提交按钮的触发逻辑中即可正常读取动态输入值:
observeEvent(input$submit_fieldmapping, { # 示例:读取所有映射关系 file_cols <- colnames(file_data()) mapping_res <- setNames( lapply(file_cols, function(col) input[[paste0("fieldmap_select_", col)]]), file_cols ) print(mapping_res) })
注:如果上传文件的列名包含特殊字符,建议先做规范化处理(比如替换空格、特殊符号为下划线),避免生成非法的HTML ID导致识别失败。
内容的提问来源于stack exchange,提问作者Kyle Weise
相关产品推荐
相关产品推荐

