我想在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)
答案 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)