在不重新渲染的情况下生成动态数量的数据表
Generating dynamic number of datatables without rerendering
我想知道处理动态数量的数据表的最佳做法是什么。这是一个玩具示例:
library(shiny)
library(DT)
ui <- shinyUI(fluidPage(
mainPanel(
sliderInput("number","Number of tables",1,10,1,1),
uiOutput("tables")
)))
server <- shinyServer(function(input, output, session) {
observe({
lapply(seq_len(input$number), function(i) {
output[[paste0("table",i)]] <- DT::renderDataTable(head(mtcars))
})
})
output$tables <- renderUI({
lapply(seq_len(input$number), function(i) {
DT::dataTableOutput(paste0("table",i))
})
})
})
# Run the application
shinyApp(ui = ui, server = server)
这种方法有点生硬,因为无论何时添加或删除单个数据表,您都必须重新呈现所有数据表。
是否有更好的动态生成输出的方法,不需要在循环中创建所有输出,因此每次发生更改时都重新创建所有输出?
[编辑] 已使用@Bárbara Borges 的解决方法更新了答案(有关其工作原理的详细信息,请参阅她的答案)
这里是一个例子,但注意它对普通表有效(不刷新),但对于数据表,删除表时不刷新但添加表时总是刷新。我认为这是由DT引起的,但还没有找到真正的原因。我发帖希望有人能改进这个。
library(shiny)
library(DT)
numUI <- 0
ui <- shinyUI(fluidPage(
mainPanel(
sliderInput("number","Number of tables",1,10,1,1),
tags$div(id="tables")
)))
server <- shinyServer(function(input, output, session) {
observe({
if (input$number > numUI) {
for (num in (numUI+1):input$number) {
insertUI("#tables", "beforeBegin", DT::dataTableOutput(paste0("table", num)))
output[[paste0("table",num)]] <- DT::renderDataTable(head(mtcars), server = FALSE)
}
}
if (input$number < numUI) {
for (num in (input$number+1):numUI) {
removeUI(paste0("#table", num))
}
}
numUI <<- input$number
})
})
# Run the application
shinyApp(ui = ui, server = server)
我是 insertUI
和 removeUI
的作者。当应用于交互式输出时,您似乎在 insertUI
中发现了错误。我向 DT 存储库中提交的原始问题提交了 issue for this in the Shiny repo and will try to get to it soon. In the meantime, a workaround is to use where = "beforeBegin"
instead of where = "beforeEnd"
in the call to insertUI()
. See my answer 以获取更多详细信息。
我想知道处理动态数量的数据表的最佳做法是什么。这是一个玩具示例:
library(shiny)
library(DT)
ui <- shinyUI(fluidPage(
mainPanel(
sliderInput("number","Number of tables",1,10,1,1),
uiOutput("tables")
)))
server <- shinyServer(function(input, output, session) {
observe({
lapply(seq_len(input$number), function(i) {
output[[paste0("table",i)]] <- DT::renderDataTable(head(mtcars))
})
})
output$tables <- renderUI({
lapply(seq_len(input$number), function(i) {
DT::dataTableOutput(paste0("table",i))
})
})
})
# Run the application
shinyApp(ui = ui, server = server)
这种方法有点生硬,因为无论何时添加或删除单个数据表,您都必须重新呈现所有数据表。
是否有更好的动态生成输出的方法,不需要在循环中创建所有输出,因此每次发生更改时都重新创建所有输出?
[编辑] 已使用@Bárbara Borges 的解决方法更新了答案(有关其工作原理的详细信息,请参阅她的答案)
这里是一个例子,但注意它对普通表有效(不刷新),但对于数据表,删除表时不刷新但添加表时总是刷新。我认为这是由DT引起的,但还没有找到真正的原因。我发帖希望有人能改进这个。
library(shiny)
library(DT)
numUI <- 0
ui <- shinyUI(fluidPage(
mainPanel(
sliderInput("number","Number of tables",1,10,1,1),
tags$div(id="tables")
)))
server <- shinyServer(function(input, output, session) {
observe({
if (input$number > numUI) {
for (num in (numUI+1):input$number) {
insertUI("#tables", "beforeBegin", DT::dataTableOutput(paste0("table", num)))
output[[paste0("table",num)]] <- DT::renderDataTable(head(mtcars), server = FALSE)
}
}
if (input$number < numUI) {
for (num in (input$number+1):numUI) {
removeUI(paste0("#table", num))
}
}
numUI <<- input$number
})
})
# Run the application
shinyApp(ui = ui, server = server)
我是 insertUI
和 removeUI
的作者。当应用于交互式输出时,您似乎在 insertUI
中发现了错误。我向 DT 存储库中提交的原始问题提交了 issue for this in the Shiny repo and will try to get to it soon. In the meantime, a workaround is to use where = "beforeBegin"
instead of where = "beforeEnd"
in the call to insertUI()
. See my answer 以获取更多详细信息。