R Shiny:将无功值传入和传出模块

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

我的最终目标是拥有一个应用程序,我可以将图表放入模块中;我希望能够放大一个图表,然后另一个模块中的图表应该相应地更新其水平轴范围。我让它可以处理两个图表,而不使用模块。

当我想将其扩展到更多数量的图表时,我决定将其实现为模块(这对我来说是新的),但我无法让它工作。我已将问题缩小到一个最小的示例,不使用图形而是使用数字输入。这说明了我可能做错了什么,但我不知道如何解决它。

我寻找其他问题/答案,但我无法理解任何答案,因此在双向沟通的情况下,它对我有用。

我有一个“全局”数字输入。我有一个还包含 numericInput 的模块。我调用该模块两次。 我打算做什么:

  1. 如果我更改其中一个模块中的值并单击按钮,全局 numericInput 就会更新(有效)。
  2. 每当全局 numericInput 更新时,模块中的 numericInput 也会更新。这不会发生。
  3. 应用程序启动时,全局 numericInput 中会设置一些默认值,需要将其“转发”到模块 numericInputs。

我猜我将 input$toplevel 传递给 testServer 的方式是罪魁祸首;显然,Shiny 似乎并不认为它需要对全局 numericInput 的变化做出反应。我需要做什么来解决这个问题?

这里是示例代码(我希望它算最少的,这是我第一次!;)):

library(shiny)


testUI <- function(id) {
  tagList(
    numericInput(NS(id, "module"), "module", value = NULL),
    actionButton(NS(id,"button"), label = "send")
  )
}

testServer <- function(id,reactinput) {
  stopifnot(is.reactive(reactinput))
  
  moduleServer(id, function(input,output,session) {
    rval <- reactiveValues(num = reactinput)
    observeEvent(rval$num,{updateNumericInput(inputId = "module")})
    
    observeEvent(input$button, {
      rval$num <- input$module
    })
    return(reactive({rval$num}))
  }) 
}

testApp <- function() {
  ui <- fluidPage(
    numericInput("global", "global", value = 5),
    testUI("test1"),
    testUI("test2")
  )
  server <- function(input, output, session) {
    val1 <- testServer("test1",reactive(input$toplevel))
    observeEvent(val1(), {updateNumericInput(inputId = "global", value = val1())})

    val2 <-testServer("test2",reactive(input$toplevel))
    observeEvent(val2(), {updateNumericInput(inputId = "global", value = val2())})
  }
  shinyApp(ui, server)  
}

testApp()
r shiny module syntax
1个回答
0
投票

您的代码存在多个问题。首先,全局输入有

inputId
global
而不是
toplevel
。其次,
reactinput
reactive
。因此,您必须使用
reactinput()
来访问该值。为此,我使用
observe
来更新模块服务器内的
rval
。第三,当更新模块中的数字输入时,您必须将
rval
的值传递给
value=
参数。

library(shiny)

testUI <- function(id) {
  tagList(
    numericInput(NS(id, "module"), "module", value = NULL),
    actionButton(NS(id, "button"), label = "send")
  )
}

testServer <- function(id, reactinput) {
  stopifnot(is.reactive(reactinput))

  moduleServer(id, function(input, output, session) {
    rval <- reactiveValues(num = NULL)
    observe({
      rval$num <- reactinput()
    })
    
    observeEvent(rval$num, {
      updateNumericInput(session, inputId = "module", value = rval$num)
    })

    observeEvent(input$button, {
      rval$num <- input$module
    })
    return(reactive({
      rval$num
    }))
  })
}

testApp <- function() {
  ui <- fluidPage(
    numericInput("global", "global", value = 5),
    testUI("test1"),
    testUI("test2")
  )
  server <- function(input, output, session) {
    val1 <- testServer("test1", reactive(input$global))
    observeEvent(val1(), {
      updateNumericInput(inputId = "global", value = val1())
    })

    val2 <- testServer("test2", reactive(input$global))
    observeEvent(val2(), {
      updateNumericInput(inputId = "global", value = val2())
    })
  }
  shinyApp(ui, server)
}

testApp()

© www.soinside.com 2019 - 2024. All rights reserved.