reactive field in Class Shiny R

て烟熏妆下的殇ゞ 提交于 2019-12-08 10:40:21

问题


Is it possible to create a reactive field in class or a class which notify app when her field change ?

I got this class which is a model for my shinyApp:

CatalogModele <- setRefClass("CatalogModele",
  fields = list(catalogs = "list"),
  methods = list(
    initialize = function(catalogs_args = list()) {
      catalogs <<- catalogs_args
    },
    add_catalog = function(key, value) {
      catalogs[[key]] <<- value 
    }
  )
)

I would like to update some shiny widgets when i use "add_catalog()" on my global object. I tried this :

catalogModele <<- reactive({CatalogModele()})
on.exit(rm(catalogModele, pos = ".GlobalEnv"))

But nothing happen when i observe my variable :

observeEvent(catalogModele(), {
    str(catalogModele()$catalogs)
})

Thanks for reading.


回答1:


I use R6 classes for a similar purpose. Maybe looking at this will help you develop a similar design for reference classes

library(R6)
library(shiny)

myClass <- R6Class(
  public = list(
    catalogs = reactiveValues(),
    add_catalog = function(key,value){
      self$catalogs[[key]] <- value
    }
  )
)

A = myClass$new()

shinyApp(
  fluidPage(
    inputPanel(
      textInput('key', 'key'),
      textInput('value', 'value'),
      actionButton('go', 'add')
    ),
    verbatimTextOutput('textOut')
  ),
  function(input, output, session){
    observeEvent(input$go,
      { A$add_catalog(input$key, input$value) }
    )
    output$textOut <- renderPrint({
      reactiveValuesToList(A$catalogs)
    })
  }
)

EDIT: Here is an actual working solution. I just wrapped the member reactives from the R6 class into a list and made it a member of the reference class.

CatalogModele <- setRefClass(
  "CatalogModele",
  fields = list(catalogs = "list"),
  methods = list(
    initialize = function(catalogs_args = list()) {
      catalogs <<- list(reactives = reactiveValues())
    },
    add_catalog = function(key, value) {
      catalogs$reactives[[key]] <<- value 
    },
    get_catalogs = function()
      reactiveValuesToList(catalogs$reactives)
  )
)

B = CatalogModele()

shinyApp(
  fluidPage(
    inputPanel(
      textInput('key', 'key'),
      textInput('value', 'value'),
      actionButton('go', 'add')
    ),
    verbatimTextOutput('textOut')
  ),
  function(input, output, session){
    observeEvent(input$go,
                 { B$add_catalog(input$key, input$value) }
    )
    output$textOut <- renderPrint(B$get_catalogs())
  }
)

In both cases, it is advisable to just make certain parts of your class reactive . Otherwise, you might encounter very poor performance in your apps.



来源:https://stackoverflow.com/questions/45063205/reactive-field-in-class-shiny-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!