在Shiny UI中访问reactiveValues的替代方法?

时间:2017-09-20 18:50:04

标签: r shiny

我想在Shiny中创建一个动态UI,每次单击一个按钮时,都会创建一个包含多个输入字段的新UI元素。我希望我可以使用reactiveValues来做这个,但是ui代码无法访问它们,所以我无法告诉它要显示多少元素。

这是一个可重现的示例,每次单击时只创建一个UI字段 - 它适用于按钮的前两次单击,但由于ui部分中的lapply被编码为固定值(在此示例中为3),之后,新的停止显示。我知道我可以将ui值设置为更高的数字,但我想要的是它是被动的。 (在完整版中,我希望每个中的嵌套元素以相同的方式工作,并且按钮也可以删除每个字段。)

server <- function(input, output) {

  rv <- reactiveValues(numFields = 1)
  #
  # start with one input box
  #
  output$textUI1 <- renderUI(textInput("textInput1", "Input #1"))
  #
  # each time the button is clicked, increase the reactive value
  #
  observeEvent(input$addField, rv$numFields <- rv$numFields + 1)
  #
  # render any additional UI input fields according to value of rv$numFields
  #
  observe({
    if(rv$numFields > 1)
    {
      lapply(2:rv$numFields, function(i) {
        output[[paste0("textUI", i)]] <- renderUI({
          textInput(paste0("textInput", i), paste0("Input #", i))
        })
      })
    }
  })
}

ui <- fluidPage(sidebarLayout(
  sidebarPanel(
    actionButton("addField", "Add text input box")
  ),

  mainPanel(
    # UI output
    lapply(1:3, function(i) { # instead of 3 I want something like rv$numFields here
      uiOutput(paste0("textUI", i))
    })
  )
))

shinyApp(ui, server)

1 个答案:

答案 0 :(得分:2)

为什么不在服务器中创建整个动态server,而不是将变量从ui传递到ui。像这样:

library (shiny)

server <- function(input, output) {

  rv <- reactiveValues(numFields = 1)
  #
  # start with one input box
  #
   output$textUI <- renderUI(textInput("textInput1", "Input #1"))
  #
  # each time the button is clicked, increase the reactive value and add a new text input

  observeEvent(input$addField,{
    rv$numFields <- rv$numFields + 1
      output$textUI <- renderUI({
        lapply(1:rv$numFields, function(i) {textInput(paste0("textInput", i), paste0("Input #", i))
      })
        })

  })
}

ui <- fluidPage(sidebarLayout(
  sidebarPanel(
    actionButton("addField", "Add text input box")
  ),

  mainPanel(
      uiOutput("textUI")
  )
))

shinyApp(ui, server)