shinyApp 中的 R R6Class 全局对象

R R6Class global obj in shinyApp

在我的 shinyApp 中,我有一个全局变量:一个 R6Class,当我的应用程序完成后,我从 globalEnv 中删除了该变量:

#' @importFrom shiny reactive
#' @export
gui <- function (port = getOption("shiny.port"),
                 host = getOption("shiny.host", "127.0.0.1"),
                 working.directory = getwd()) {
  appDir <- system.file("shiny", "gui", package = "lidRGUI")
  if (appDir == "") {
    stop("Could not find shiny directory. Try re-installing `lidRGUI`.", call. = FALSE)
  }


  catalogModele <<- CatalogModele$new()
  csvPlotsModel <<- CSVPlotsModel$new()


  on.exit({
    rm(list = c("catalogModele", "csvPlotsModel"), pos = ".GlobalEnv")
    gc()
  })

  shiny::runApp(appDir, display.mode = "normal")
}

#----------------------------------
# Catalog Modele Class
#----------------------------------
#' @importFrom R6 R6Class
#' @importFrom shiny reactiveValues 

#' @export CatalogModele
CatalogModele <- R6Class(
  public = list(
    catalogs = reactiveValues(),
    add_catalog = function(key,value) {
      self$catalogs[[key]] <- value
    },
    get_catalog = function(key) {
      return(self$catalogs[[key]])
    },
    finalize =  function() {
      print("Finalize has been called!")
    }
  )
)

我第一次启动 gui() catalogModele$catalogs 是空的,但在第一次启动后 catalogModele$catalogs 计数所有以前的初始化。

我找到了解决方案,但我不知道为什么会这样。我替换了:

public = list(
    catalogs = reactiveValues(),

来自

public = list(
    catalogs = NULL,
    initialize = function() {
      self$catalogs <- reactiveValues()
    },

此行为记录在 R6 vignettes

If your R6 class contains any fields that also have reference semantics (e.g., other R6 objects, and environments), those fields should be populated in the initialize method. If the field set to the reference object directly in the class definition, that object will be shared across all instances of the R6 objects.

reactiveValues(以及 reactiveVal)具有提到的引用语义 here。这就是为什么您发布的解决方案给出了预期的结果,而您问题中的代码在 class.

的所有实例中导致 "shared catalog"

抱歉,我在写 的答案时没有考虑到这一点,但如果您需要,我可以更正。