R R6Class global obj in shinyApp

时间:2017-07-13 13:09:02

标签: r package shiny reactive

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

#' @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会计算所有先前的启动。

2 个答案:

答案 0 :(得分:0)

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

public = list(
    catalogs = reactiveValues(),

通过

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

答案 1 :(得分:0)

R6 vignettes

中记录了此行为
  

如果您的R6类包含任何也具有引用语义的字段(例如,其他R6对象和环境),则应在initialize方法中填充这些字段。如果字段直接在类定义中设置为引用对象,则该对象将在R6对象的所有实例之间共享。

reactiveValues(以及reactiveVal)具有所提及的引用语义here。这就是为什么您发布的解决方案会提供预期结果,而您的问题中的代码会导致共享目录&#34;在所有班级中。

抱歉,当我写下this question of yours的答案时,我没有想到这一点,但如果你愿意,我可以纠正。