r - 是否可以将传单 map 传递到另一个模块?

标签 r shiny leaflet reactive-programming shiny-reactivity

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

Error in if: missing value where TRUE/FALSE needed

是否可以将 map 传递到另一个模块?并在那里使用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)

最佳答案

看来您需要将传单代理作为响应传递给模块才能使其工作。

在模块 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)

关于r - 是否可以将传单 map 传递到另一个模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67167626/

相关文章:

javascript - 在 LeafLet map 上显示 jQuery 动态 GeoJSON 内容

删除嵌套列表中的重复项

r - 将函数参数传递给 ddply

r - "no observations from which to fit a model"错误

r - shinydashboard:通过textInput过滤DT

javascript - 将 geoJSON 要素属性添加到 Mapbox 弹出窗口

javascript - 使用 javascript 时从 Shiny 的应用程序下载绘图时出错

在Shiny中输入后运行R脚本

r - 将 R shiny checkboxGroupInput 与其他输入选择相结合

javascript - 如何删除/清除传单中的标记?