【发布时间】:2018-01-09 12:46:23
【问题描述】:
是否可以在 downloadHandler 的内容部分中设置 reactiveValues?我试过了,不明白这种行为。
一个简单的例子可以是一个显示下载按钮被点击频率的计数器:
library(shiny)
ui <- fluidPage(
downloadButton("downloadData", "Download"),
textOutput("nDownloads"),
actionButton("trig", "get number")
)
server <- function(input, output) {
# Our dataset
data <- mtcars
r.nDownloads <- reactiveValues(n=0)
output$nDownloads <- renderText({
input$trig
paste("number of downloads:", r.nDownloads$n)
})
output$downloadData <- downloadHandler(
filename = function() {
paste("data-", Sys.Date(), ".csv", sep="")
},
content = function(file) {
r.nDownloads$n <- r.nDownloads$n + 1
write.csv(data, file)
}
)
}
shinyApp(ui, server)
如果单击下载按钮,则 textOutput 显示为灰色,但未更新。我添加了一个操作按钮作为触发器来强制更新 renderText。令人惊讶的是(至少对我而言)这有效:显示了正确的数字。
所以,由于某种原因,reactiveValue 被 downloadHandler 改变了,但是它的依赖只是失效了,而不是更新了。
当然,正确的方法是让“数据”对象反应并在那里进行计数。但我很好奇如何解释所描述的行为。
编辑:
好的,现在我真的很困惑:我尝试了上面提到的方法:使“数据”具有反应性并在那里进行计数。这不再是简单的下载计数,因为只有在无效时才会重新计算数据反应。
这是一个示例,其中包含用于“数据”无效的附加输入:
library(shiny)
ui <- fluidPage(
numericInput("nRows", label = "nRows", min=1, max=32, value=15),
downloadButton("downloadData", "Download"),
textOutput("nDownloads")
)
server <- function(input, output) {
r.nDownloads <- reactiveValues(n=0)
# Our dataset
data <- reactive({
isolate({
r.nDownloads$n <- r.nDownloads$n + 1
})
mtcars[1:input$nRows,]
})
output$nDownloads <- renderText({
paste("number of downloads:", r.nDownloads$n)
})
output$downloadData <- downloadHandler(
filename = function() {
paste("data-", Sys.Date(), ".csv", sep="")
},
content = function(file) {
write.csv(data(), file)
}
)
}
shinyApp(ui, server)
但是,我仍然看到类似的行为:单击下载按钮会使文本变灰,更改“nRows”会产生预期的下载次数(现在 nRows 更改后的下载次数;- )) 出现。
现在我遇到了一个实际问题:在我的真实应用程序中,可以下载一个相当复杂的 Excel 文件。在准备和格式化 Excel 文件时,可能会发生一些事件,这些事件会导致应用程序做出某些反应。这就是为什么下载应该触发一些东西。我可以看到的替代方法是,在用户点击下载之前准备 Excel 文件(我想避免这种情况,因为这可能需要几秒钟,具体取决于文件/格式的复杂性) .
我是否遗漏了一些明显的东西?如果没有,我会很感激任何想法,下载事件如何触发应用程序的其余部分。
【问题讨论】: