难以让htmlwidgets :: onStaticRenderComplete与传单一起使用

时间:2017-12-29 20:59:47

标签: r shiny leaflet

我正在使用Shiny并尝试创建与leafletProxy一起使用的同步传单地图。应该在传单小部件渲染之后运行的脚本似乎没有被调用。

library(shiny)
library(leaflet)

# Modified from mapview::latticeView

sync <- function (..., ncol = 2, sync = "none", sync.cursor = FALSE,
no.initial.sync = TRUE) 
{
  ls <- list(...)
  if (length(ls) == 1) 
    ls <- ls[[1]]

  for (i in seq(ls)) {
    if (!is.null(ls[[i]]$id)) {
      ls[[i]]$elementId <- ls[[i]]$id
    }

    #ls[[i]] <- mapview:::mapview2leaflet(ls[[i]])

    if (length(ls[[i]]$dependencies) == 0) {
      ls[[i]]$dependencies = list()
    }
    if (is.null(ls[[i]]$elementId)) {
      ls[[i]]$elementId <- paste("htmlwidget", as.integer(stats::runif(1, 
                                                                       1, 10000)), sep = "-")
    }
  }
  wdth <- paste0("width:", round(1/ncol * 100, 0) - 1, "%;")
  styl <- paste0("display:inline;", wdth, "float:left;border-style:solid;border-color:#BEBEBE;border-width:1px 1px 1px 1px;")

  tg <- lapply(seq(ls), function(i) {
    htmltools::tags$div(style = styl, leafletOutput(ls[[i]]$id))
  })

  sync_strng <- ""

  if (!is.list(sync) && sync == "all") {
    sync = list(seq(ls))
  }

  if (is.list(sync)) {
    for (i in seq(sync)) {
      synci <- sync[[i]]
      sync_grid <- expand.grid(synci, synci, KEEP.OUT.ATTRS = FALSE)
      sync_strng <- c(sync_strng, apply(sync_grid, MARGIN = 1, 
                                        function(combo) {
                                          if (combo[1] != combo[2]) {
                                            return(sprintf("leaf_widgets['%s'].sync(leaf_widgets['%s'],{syncCursor: %s, noInitialSync: %s});", 
                                                           ls[[combo[1]]]$elementId, ls[[combo[2]]]$elementId, 
                                                           tolower(as.logical(sync.cursor)), tolower(as.logical(no.initial.sync))))
                                          }
                                          return("")
                                        }))
    }
  }
  sync_strng <- paste0(sync_strng, collapse = "\n")
  tl <- htmltools::attachDependencies(htmltools::tagList(tg, 
                                                         htmlwidgets::onStaticRenderComplete(paste0("
                                                                                   var leaf_widgets = {}; \n                
                                                                                                    Array.prototype.map.call( \n                 
                                                                                                    document.querySelectorAll(\".leaflet\"),\n                   
                                                                                                    function(ldiv){\n
                                                                                                    if (HTMLWidgets.find(\"#\" + ldiv.id) && HTMLWidgets.find(\"#\" + ldiv.id).getMap()) {\n 
                                                                                                    leaf_widgets[ldiv.id] = HTMLWidgets.find(\"#\" + ldiv.id).getMap();\n                     
                                                                                                    }\n                   }\n                );\n               ", 
                                                                                                    sync_strng))), mapview:::dependencyLeafletsync())
  return(htmltools::browsable(tl))
}


ui <- function(id) {

    uiOutput("maps")

}

server <- function(input,output,session) {

  map1 <- leaflet() %>% addTiles()
  map2 <- leaflet() %>% addTiles()

  output$map1 <- renderLeaflet(map1)
  output$map2 <- renderLeaflet(map2)

  output$maps <- renderUI({
    sync2(leafletProxy('map1'), leafletProxy('map2'), sync = "all", sync.cursor = TRUE, no.initial.sync = FALSE)
  })
}

runApp(shinyApp(ui, server), launch.browser=TRUE)

当页面加载时,地图不会同步,但如果我进入控制台并执行window.HTMLWidgets.staticRender(),则会运行后期渲染代码并同步地图。造成这种情况的原因是什么?

0 个答案:

没有答案