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

如何在Shiny应用中实现reactable与leaflet模块的联动?

解决Shiny模块化中reactable多选与leaflet联动失效问题

核心问题定位

模块化重构后功能失效,通常是因为模块内输入输出的作用域未正确隔离、reactable选中状态的监听未绑定模块session,或是leaflet更新逻辑未适配模块环境。以下是修正后的完整代码及关键说明:

修正后的模块化代码

模块UI定义

mapTableUI <- function(id) {
  ns <- NS(id)
  tagList(
    reactableOutput(ns("data_table")),
    actionButton(ns("clear_selection"), "清除选择"),
    leafletOutput(ns("data_map"))
  )
}

模块Server定义

mapTableServer <- function(id, data) {
  moduleServer(id, function(input, output, session) {
    ns <- session$ns
    
    # 渲染reactable表格,开启多选
    output$data_table <- renderReactable({
      reactable(
        data,
        selection = "multiple",
        inputId = ns("table_selected"), # 必须绑定模块命名空间
        columns = list(
          lat = colDef(show = FALSE),
          lng = colDef(show = FALSE)
        )
      )
    })
    
    # 初始化地图,显示全部数据点
    output$data_map <- renderLeaflet({
      leaflet(data) %>%
        addTiles() %>%
        addMarkers(lng = ~lng, lat = ~lat, popup = ~name)
    })
    
    # 监听表格选中变化,更新地图
    observeEvent(input$table_selected, {
      selected_rows <- input$table_selected
      if (length(selected_rows) > 0) {
        selected_data <- data[selected_rows, ]
        leafletProxy(ns("data_map"), session = session) %>%
          clearMarkers() %>%
          addMarkers(data = selected_data, lng = ~lng, lat = ~lat, popup = ~name)
      } else {
        # 无选中时显示全部数据
        leafletProxy(ns("data_map"), session = session) %>%
          clearMarkers() %>%
          addMarkers(data = data, lng = ~lng, lat = ~lat, popup = ~name)
      }
    })
    
    # 清除选择按钮逻辑:清空表格选中并恢复全量地图
    observeEvent(input$clear_selection, {
      updateReactable(session, "table_selected", selected = NA)
      leafletProxy(ns("data_map"), session = session) %>%
        clearMarkers() %>%
        addMarkers(data = data, lng = ~lng, lat = ~lat, popup = ~name)
    })
    
    # 返回模块内的选中状态(可选,供外部使用)
    return(reactive(input$table_selected))
  })
}

主程序调用

library(shiny)
library(reactable)
library(leaflet)

# 示例数据
sample_data <- data.frame(
  name = c("地点A", "地点B", "地点C", "地点D"),
  lat = c(39.9042, 31.2304, 23.1291, 30.2741),
  lng = c(116.4074, 121.4737, 113.2644, 120.1551)
)

ui <- fluidPage(
  mapTableUI("map_table_module")
)

server <- function(input, output, session) {
  mapTableServer("map_table_module", data = sample_data)
}

shinyApp(ui, server)

关键修正点说明

  1. 模块命名空间绑定:所有输入输出ID必须通过ns()函数包裹,确保模块内的作用域独立,避免与其他模块或主程序冲突。
  2. reactable选中状态监听:reactable的inputId必须设置为模块命名空间内的ID,确保input$table_selected能正确获取选中行。
  3. leafletProxy的使用:更新地图时使用leafletProxy而非重新渲染整个地图,同时指定session = session确保在模块环境中生效。
  4. 清除选择的同步逻辑:点击按钮时,用updateReactable清空表格选中状态,同时调用leafletProxy恢复全量标记,保证表格与地图状态一致。

内容的提问来源于stack exchange,提问作者Antônio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:22:50