我想在 Shiny 中创建一个动态 UI,每次单击一个按钮时,都会创建一个包含多个输入字段的新 UI 元素。我希望我可以使用 reactiveValues 来做到这一点,但是 ui 代码无法访问它们,所以我无法告诉它要显示多少元素。
这是一个可重现的示例,每次点击时只创建一个 UI 字段 - 它适用于按钮的前两次点击,但由于 ui 部分中的 lapply 被编码为固定值(本例中为 3),之后新的停止显示。我知道我可以将 ui 值设置为更高的数字,但我想要的是它是 react 性的。 (在完整版本中,我希望每个元素中的嵌套元素都以相同的方式工作,以及用于删除每个字段的按钮。)
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)
最佳答案
与其将变量从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)
关于r - 在 Shiny UI 中访问 reactiveValues 的替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46329695/