如何使用reactiveValues代替reactiveVal作为模块参数?

问题描述 投票:0回答:1

工作最小示例

我正在尝试使用包

shinyjs
禁用模块 UI。在主应用程序中,我使用名为
enabled
:

的反应性参数
library(shiny)
library(shinyjs)

# ____________________________________________
##########
# MODULE #
##########

subUI <- function(id) {
  ns <- NS(id)
  tagList(
    useShinyjs(),
    actionButton(ns("click"), "CLICK!")
  )
}

subServer <- function(id, enabled) {
  stopifnot(is.reactive(enabled))
  moduleServer(
    id,
    function(input, output, session) {
      observe({
        if(enabled()) {
          enable("click")
        } else {
          disable("click")
        }
      })
    }
  )
}

# ____________________________________________
##############
# MAIN APP   #
##############
ui <- fluidPage(
  actionButton("toggle", "Toggle"),
  subUI("sub")
)

server <- function(input, output, session) {
  
  enabled <- reactiveVal(TRUE)
  
  
  subServer("sub", enabled)
  
  observeEvent(input$toggle, { enabled(! enabled()) })
}

shinyApp(ui, server, options = list(
  launch.browser = TRUE
))

问题

在我的真实应用程序中,我有很多反应值需要处理,并且我正在使用

reactiveValues()
代替
reactiveVal()
但我无法适应上面的示例。我试过了:


library(shiny)
library(shinyjs)

# ____________________________________________
##############
# SUB MODULE #
##############

subUI <- function(id) {
  ns <- NS(id)
  tagList(
    useShinyjs(),
    actionButton(ns("click"), "CLICK!")
  )
}

subServer <- function(id, enabled) {
  # stopifnot(is.reactive(enabled))
  
  moduleServer(
    id,
    function(input, output, session) {
      observe({
        if(enabled) {
          enable("click")
        } else {
          disable("click")
        }
      })
    }
  )
}

# ____________________________________________
##############
# MAIN APP   #
##############
ui <- fluidPage(
  actionButton("toggle", "Toggle"),
  subUI("sub")
)

server <- function(input, output, session) {
  
  r <- reactiveValues()
  r$enabled <- TRUE
  
  subServer("sub", r$enabled)
  
  observeEvent(input$toggle, { r$enabled <- ! r$enabled })
}

shinyApp(ui, server, options = list(
  launch.browser = TRUE
))

注意:我必须在子模块服务器中注释掉这一行

# stopifnot(is.reactive(enabled))
,这会引发一个我无法理解的错误:


Error in r$enabled : 
  Can't access reactive value 'enabled' outside of reactive consumer.

我认为

is.reactive()
的目的是处理无功值......

r shiny reactive shinyjs
1个回答
1
投票

以下是两种示例方法。 第一个,简单地将reactiveValue包装在reactive()中,因此它与您最初的工作设计紧密结合。 第二个,传递整个reactiveValues对象并进行相关测试,并就地使用它,也许它是您正在寻找的,不清楚您更喜欢哪个。

1)

library(shiny)
library(shinyjs)

# ____________________________________________
##############
# SUB MODULE #
##############

subUI <- function(id) {
  ns <- NS(id)
  tagList(
    useShinyjs(),
    actionButton(ns("click"), "CLICK!")
  )
}

subServer <- function(id, enabled) {
  stopifnot(is.reactive(enabled))
  moduleServer(
    id,
    function(input, output, session) {
      observe({
        if(enabled()) {
          enable("click")
        } else {
          disable("click")
        }
      })
    }
  )
}

# ____________________________________________
##############
# MAIN APP   #
##############
ui <- fluidPage(
  actionButton("toggle", "Toggle"),
  subUI("sub")
)

server <- function(input, output, session) {
  
  r <- reactiveValues()
  r$enabled <- TRUE
  
  
  subServer("sub", reactive(r$enabled))
  
  observeEvent(input$toggle, {
    r$enabled <- !r$enabled
    })
}

shinyApp(ui, server, options = list(
  launch.browser = TRUE
))

2)

library(shiny)
library(shinyjs)

# ____________________________________________
##############
# SUB MODULE #
##############

subUI <- function(id) {
  ns <- NS(id)
  tagList(
    useShinyjs(),
    actionButton(ns("click"), "CLICK!")
  )
}

subServer <- function(id, enabled_container) {
  stopifnot(is.reactivevalues(enabled_container))

  
  moduleServer(
    id,
    function(input, output, session) {
      observe({
        if(enabled_container$enabled) {
          enable("click")
        } else {
          disable("click")
        }
      })
    }
  )
}

# ____________________________________________
##############
# MAIN APP   #
##############
ui <- fluidPage(
  actionButton("toggle", "Toggle"),
  subUI("sub")
)

server <- function(input, output, session) {
  
  r <- reactiveValues()
  r$enabled <- TRUE
  
  
  subServer("sub", r )
  
  observeEvent(input$toggle, {
    r$enabled <- !r$enabled
  })
}

shinyApp(ui, server, options = list(
  launch.browser = TRUE
))
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.