如何在Shiny应用中动态移除外部包中的模块UI?
解决Shiny中移除外部包模块UI的问题
你遇到的问题根源是:外部包(比如mapedit的editMod)生成的模块UI结构,并非直接以你指定的模块ID作为顶层元素的ID,导致removeUI用#current_id找不到目标元素。
解决思路
给外部模块的UI套一层自定义的div,并将这个div的ID设为你跟踪的模块ID。这样removeUI就能精准定位到这个外层容器,一次性移除整个模块的UI。
修改后的代码
library(shiny) library(ggplot2) library(mapedit) library(leaflet) ui <- fluidPage( actionButton( inputId = "add_module", label = "Add a module" ), actionButton( inputId = "remove_module", label = "Remove a module" ), div( id = "add_here" ) ) server <- function(input, output, session) { active_modules <- reactiveVal(value = NULL) # leaflet blank map for module map <- leaflet() %>% addProviderTiles(providers$CartoDB.Positron) observeEvent(input$add_module, { current_id <- paste0("id_", input$add_module) active_modules(c(current_id, active_modules())) callModule(editMod, map, id = current_id) insertUI( selector = "#add_here", # 给外部模块UI套一层自定义div,用current_id作为这个div的ID ui = div( id = current_id, editModUI(id = current_id) ) ) }) observeEvent(input$remove_module, { # only remove a module if there is at least one module shown if (length(active_modules()) > 0) { current_id <- active_modules()[1] removeUI( selector = paste0("#", current_id) ) # update the list of currently shown modules active_modules(active_modules()[-1]) } }) } shinyApp(ui, server)
补充说明
如果不想套外层div,也可以通过浏览器开发者工具(F12)查看editModUI生成的HTML结构,找到它的顶层容器ID或类,再调整removeUI的selector。比如假设editModUI生成的顶层元素ID是paste0(current_id, "-map"),那selector就改成paste0("#", current_id, "-map")。但套自定义div的方法更通用,不需要依赖外部模块的内部结构。
内容的提问来源于stack exchange,提问作者r2d2
相关产品推荐
相关产品推荐

