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

如何在Shiny模块的modalDialog中动态生成并捕获用户输入?

问题根因

  1. 动态生成的selectInput未添加模块命名空间:Shiny模块内所有自定义输入ID都需要通过session$ns()封装,否则模块的输入作用域无法匹配到对应的动态控件值
  2. JS回调配置错误:原代码给表格行添加了滑块输入专属类shiny-input-slider-input,和下拉选择控件的类型不匹配,额外添加行ID/类的逻辑属于冗余代码,反而会干扰Shiny的输入绑定
  3. 绑定时机逻辑存在隐患:原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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:39:00