R Shiny : How to pass reactive variables between nested modules

标签 r shiny

我创建了一个玩具示例,其中会弹出一个 textInput() 框供用户输入任何字符串,然后单击添加按钮,会弹出一个 selectInput() 框,其中包含前面带有字符串的字母 a:d .换句话说,如果用户输入“1”,那么通过单击“添加”按钮,会弹出一个 selectInput() 框,其中有 1a、1b、1c 和 1d 作为选项。我正在使用一个模块来实现添加/删除按钮功能,并且该模块调用另一个模块来生成 selectInput() 框。主服务器函数调用添加/删除模块,该模块调用“第一个”模块,该模块生成 selectInput() 框。我将 a() 作为 react 元素传递给添加/删除模块,然后将其传递给“第一个”模块。我只是在添加/删除模块和“第一个”模块的函数签名中使用“...”来获取嵌套模块的 a()。

这似乎可行,虽然 a() 在到达“第一个”模块时似乎没有反应,这意味着如果我在“a”框中键入不同的字符串,我希望在selectInput() 框动态更改,或者至少当我更改 textInput() 字符串并单击“添加”时,新的 selectInput() 应该反射(reflect)更新的 textInput() 字符串,但这不会发生。什么会使 selectInput() 选项随着 textInput() 的变化而动态变化?代码如下,谢谢!

library(shiny)

firstUI <- function(id) { uiOutput(NS(id, "first")) }

firstServer <- function(input, output, session, a) {

    output$first <- renderUI({
        selectInput(session$ns("select"), h4("Select"), paste0(a,letters[1:4]))
    })
}

removeFirstUI <- function(id) {
    removeUI(selector = paste0('#', NS(id, "first")))
}

addRmBtnUI <- function(id) {
    ns <- NS(id)

    tags$div(
    actionButton(inputId = ns('insertParamBtn'), label = "Add"),
    actionButton(ns('removeParamBtn'), label = "Remove"),
    hr(),
    tags$div(id = ns('placeholder'))
  )
}

addRmBtnServer <- function(input, output, session, moduleToReplicate,...) {
    ns = session$ns

    params <- reactiveValues(btn = 0)

    observeEvent(input$insertParamBtn, {
        params$btn <- params$btn + 1

        callModule(moduleToReplicate$server, id = params$btn, ...)
        insertUI(
      selector = paste0('#', ns('placeholder')),
      ui = moduleToReplicate$ui(ns(params$btn))
    )
    })

    observeEvent(input$removeParamBtn, {
        moduleToReplicate$remover(ns(params$btn))
        params$btn <- params$btn - 1
    })
}

ui <- fluidPage(
          addRmBtnUI("addRm"),
          textInput("a", label = "a", value = 1, width = '150px') )

server <- function(input, output, session) {


    a <- reactive({ input$a })
    callModule(
    addRmBtnServer, id = "addRm",
    moduleToReplicate = list(
      ui = firstUI,
      server = firstServer,
      remover = removeFirstUI
    ), a = a()
  )
}

shinyApp(ui = ui, server = server)

最佳答案

如果你有

a <- reactive({input$a})

您需要将 a 传递给内部(第一个)模块,而不是 a()。那是因为a() 代表了可观察对象acurrent 值。这意味着 a()不可观察的。在您的代码中,a() 在启动期间在服务器范围内进行评估。那时,a 的值为 1(对应的 textInput 中定义的默认值),您将其作为 static 传递 对象。

您可以了解有关 react 值的更多信息 here .

library(shiny)

firstUI <- function(id) { uiOutput(NS(id, "first")) }

firstServer <- function(input, output, session, a) {

  output$first <- renderUI({
    selectInput(session$ns("select"), h4("Select"), paste0(isolate(a()),letters[1:4]))
  })
}

removeFirstUI <- function(id) {
  removeUI(selector = paste0('#', NS(id, "first")))
}

addRmBtnUI <- function(id) {
  ns <- NS(id)

  tags$div(
    actionButton(inputId = ns('insertParamBtn'), label = "Add"),
    actionButton(ns('removeParamBtn'), label = "Remove"),
    hr(),
    tags$div(id = ns('placeholder'))
  )
}

addRmBtnServer <- function(input, output, session, moduleToReplicate,...) {
  ns = session$ns

  params <- reactiveValues(btn = 0)

  observeEvent(input$insertParamBtn, {
    params$btn <- params$btn + 1

    callModule(moduleToReplicate$server, id = params$btn, ...)
    insertUI(
      selector = paste0('#', ns('placeholder')),
      ui = moduleToReplicate$ui(ns(params$btn))
    )
  })

  observeEvent(input$removeParamBtn, {
    moduleToReplicate$remover(ns(params$btn))
    params$btn <- params$btn - 1
  })
}

ui <- fluidPage(
  addRmBtnUI("addRm"),
  textInput("a", label = "a", value = 1, width = '150px') )

server <- function(input, output, session) {


  a <- reactive({ input$a })
  callModule(
    addRmBtnServer, id = "addRm",
    moduleToReplicate = list(
      ui = firstUI,
      server = firstServer,
      remover = removeFirstUI
    ), 
    a = a
  )
}

shinyApp(ui = ui, server = server)

关于R Shiny : How to pass reactive variables between nested modules,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46578703/

相关文章:

r - Shiny react

r - 使用 fileInput Shiny R 打开特定目录

performance - 提高性能/速度

r - 按组填写缺少的日期

html - 使用标签在 Shiny - R 中创建下拉菜单

R Shiny 所需的包和 Github

r - 如何获取 Flexdashboard 文档中当前事件的选项卡以响应式显示不同的 UI

r - 如何绑定(bind)行而不丢失带有字符(0)的行?

r - 如何通过R中列中NA的数量来改变列的顺序?

r - 添加或删除输入后保留 UI 文本输入