Golem模块中Shiny CRUD的编辑/删除按钮无法触发模态框
解决Shiny Golem模块中CRUD编辑/删除按钮无法触发模态框的问题
问题核心原因
- 自定义按钮ID未添加模块命名空间前缀,Shiny无法识别模块内的按钮输入
- JS函数中设置的
current_id输入未绑定模块命名空间,导致值无法传递到模块Server - DT表格渲染时未正确处理HTML按钮(缺少
escape = FALSE配置)
具体修改步骤
1. 给自定义按钮ID添加模块命名空间
修改create_btns函数,用ns()包裹按钮ID,确保生成的ID带有模块前缀:
global$create_btns <- function(x) { x %>% purrr::map_chr(~ paste0( '<div class = "btn-group">', '<button class="btn btn-default action-button btn-info action_button" id="', ns(paste0("edit_", .x)), '" type="button" onclick=get_id("', ns("current_id"), '", this.id)>', '<i class="fas fa-edit"></i>', '</button>', '<button class="btn btn-default action-button btn-danger action_button" id="', ns(paste0("delete_", .x)), '" type="button" onclick=get_id("', ns("current_id"), '", this.id)>', '<i class="fa fa-trash-alt"></i>', '</button>', '</div>' )) }
2. 更新JS函数以支持模块命名空间
修改script.js,让函数接受目标输入ID参数,确保输入值传递到模块对应的input$current_id:
function get_id(targetInputId, clicked_id) { Shiny.setInputValue(targetInputId, clicked_id, {priority: "event"}); }
3. 确保DT表格正确渲染HTML按钮
在模块Server中添加DT输出代码,设置escape = FALSE以渲染按钮的HTML:
output$dt_table <- DT::renderDT({ req(global$CRUD$df) DT::datatable( global$CRUD$df, escape = FALSE, # 关键:不转义HTML内容 selection = "none", rownames = FALSE, options = list( dom = "t", ordering = FALSE, columnDefs = list(list(targets = ncol(global$CRUD$df)-1, orderable = FALSE)) ) ) })
4. 监听模块内的current_id输入
在模块Server中添加对input$current_id的监听,触发编辑/删除逻辑:
observeEvent(input$current_id, { req(input$current_id) btn_id <- input$current_id # 区分编辑和删除按钮 if (stringr::str_starts(btn_id, ns("edit_"))) { item_id <- stringr::str_remove(btn_id, ns("edit_")) # 触发编辑模态框逻辑(替换为你的模态框调用代码) global$CRUD$edit_button <- item_id # showModal(mod_edit_ui(ns("edit_modal"))) } else if (stringr::str_starts(btn_id, ns("delete_"))) { item_id <- stringr::str_remove(btn_id, ns("delete_")) # 触发删除逻辑(替换为你的删除确认/执行代码) # showModal(mod_delete_confirm_ui(ns("delete_modal"))) } })
额外注意事项
- 确保
includeScript的路径正确,Golem项目中推荐用golem_add_external_resources管理静态资源,或确认system.file能正确定位脚本文件 - 若使用DT的server-side模式(
server = TRUE),需额外处理按钮点击事件,建议先用server = FALSE测试 - 检查模态框的UI元素是否也添加了模块命名空间(模态框内的输入/输出ID需用
ns()包裹)
内容的提问来源于stack exchange,提问作者TT95F
相关产品推荐
相关产品推荐

