【问题标题】:Is it possible to pass leaflet map to another module?是否可以将传单地图传递给另一个模块?
【发布时间】:2021-07-13 23:35:00
【问题描述】:

我编写了一个尝试模块化的应用程序。一般来说,我将传单地图添加到我的应用程序主体(在主模块中),我想做的是编写一些其他模块来引用我的主地图(在地图上显示/隐藏点和其他空间操作)。我尝试从其他模块中引用此地图(位于主模块中)。在下面的示例中,我将 map 作为响应式表达式从主模块传递,但是当我按下在地图上显示点的按钮时,会出现错误:

Error in if: missing value where TRUE/FALSE needed

是否可以将地图传递给另一个模块?并在那里使用leafletProxy

这是可重现的示例:

library(shiny)
library(dplyr)
library(sf)
library(leaflet)



moduleServer <- function(id, module) {
    callModule(module, id)
}

# Main module - UI 1 #
mod_btn_UI1 <- function(id) {
    
    ns <- NS(id)
    tagList(
        leafletOutput(ns("map")),
        mod_btn_UI2(ns("other"))
    )
}

# Main module - Server 1 #
mod_btn_server1 <- function(id){
    moduleServer(id, function(input, output, session) {
        
      ns <- NS(id)
      
      # here I pass map as reactive
      passMap = reactive({input$map})
      
      coords <- quakes %>%
        sf::st_as_sf(coords = c("long","lat"), crs = 4326)
      
    
        output$map <- leaflet::renderLeaflet({
          leaflet::leaflet() %>% 
            leaflet::addTiles() %>% 
            leaflet::setView(172.972965,-35.377261, zoom = 4) %>%
            leaflet::addCircleMarkers(
              data = coords,
              stroke = FALSE,
              radius = 6)
        })
        
        mod_btn_server2("other", passMap)  
        
             
    })
}


# Other module - UI 2 #
mod_btn_UI2 <- function(id) {
  
  ns <- NS(id)
  tagList(
    actionButton(inputId = ns("btn"), label = "show points")
  )
}


# Other module - Server 2 #
mod_btn_server2 <- function(id, passMap){
  moduleServer(id, function(input, output, session) {
    
    ns <- NS(id)
    
    coords <- quakes %>%
      sf::st_as_sf(coords = c("long","lat"), crs = 4326)
    
    observeEvent(input$btn, {
      leaflet::leafletProxy(passMap()) %>%
        leaflet::addCircleMarkers(
          data = coords,
          stroke = TRUE,
          color = "red",
          radius = 6)

    })
    
  })
}



# Final app #

ui <- fluidPage(
    
    tagList(
        mod_btn_UI1("test-btn"))

)

server <- function(input, output, session) {
    
    mod_btn_server1("test-btn")
    
}

shinyApp(ui = ui, server = server)

【问题讨论】:

    标签: r shiny leaflet reactive-programming shiny-reactivity


    【解决方案1】:

    您似乎需要将传单代理作为对模块的反应传递给它才能工作。

    为模块 mod_btn_server1 中的变量 passMap 添加了传单代理而不是输入名称:

    proxymap <- reactive(leafletProxy('map'))  
    
    mod_btn_server2("other", proxymap)  
    

    在 mod_btn_server2 中,您必须将 Passmap 更改为 Leafletproxy 本身,从而消除对 Leafletproxy 的调用:

        observeEvent(input$btn, {
      passMap() %>%
        leaflet::addCircleMarkers(
          data = coords,
          stroke = TRUE,
          color = "red",
          radius = 6)
      
    })
    

    完整代码在这里:

    library(shiny)
    library(dplyr)
    library(sf)
    library(leaflet)
    
    
    
    moduleServer <- function(id, module) {
      callModule(module, id)
    }
    
    # Main module - UI 1 #
    mod_btn_UI1 <- function(id) {
      
      ns <- NS(id)
      tagList(
        leafletOutput(ns("map")),
        mod_btn_UI2(ns("other"))
      )
    }
    
    # Main module - Server 1 #
    mod_btn_server1 <- function(id){
      moduleServer(id, function(input, output, session) {
        
        ns <- NS(id)
        
        # here I pass map as reactive
        passMap = reactive({input$map})
        
        coords <- quakes %>%
          sf::st_as_sf(coords = c("long","lat"), crs = 4326)
        
        
        output$map <- leaflet::renderLeaflet({
          leaflet::leaflet() %>% 
            leaflet::addTiles() %>% 
            leaflet::setView(172.972965,-35.377261, zoom = 4) %>%
            leaflet::addCircleMarkers(
              data = coords,
              stroke = FALSE,
              radius = 6)
        })
        proxymap <- reactive(leafletProxy('map'))  
    
        mod_btn_server2("other", proxymap)  
        
        
      })
    }
    
    
    # Other module - UI 2 #
    mod_btn_UI2 <- function(id) {
      
      ns <- NS(id)
      tagList(
        actionButton(inputId = ns("btn"), label = "show points")
      )
    }
    
    
    # Other module - Server 2 #
    mod_btn_server2 <- function(id, passMap){
      moduleServer(id, function(input, output, session) {
        
        ns <- NS(id)
        
        coords <- quakes %>%
          sf::st_as_sf(coords = c("long","lat"), crs = 4326)
        
        observeEvent(input$btn, {
          passMap() %>%
            leaflet::addCircleMarkers(
              data = coords,
              stroke = TRUE,
              color = "red",
              radius = 6)
          
        })
        
      })
    }
    
    
    
    # Final app #
    
    ui <- fluidPage(
      
      tagList(
        mod_btn_UI1("test-btn"))
      
    )
    
    server <- function(input, output, session) {
      
      mod_btn_server1("test-btn")
      
    }
    
    shinyApp(ui = ui, server = server)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      • 2019-02-15
      • 1970-01-01
      • 1970-01-01
      • 2013-01-16
      相关资源
      最近更新 更多