根据您的评论:
是的,数据处理取决于用户输入。USer 将上传一些文件并单击一个Action 按钮开始处理。下载按钮位于选项卡集中。
假设操作按钮名为input$start_proc
。
在 server.R 中:
shinyServer(function(input, output, session) {
#... other code
observe({
if (input$start_proc > 0) {
# crunch data...
# when data is ready:
session$sendCustomMessage("download_ready", list(...))
# you can put extra information you want to send to the client
# in the ... part.
}
})
#... other code
})
然后在ui.R中,您可以编写一些 javascript 来处理自定义消息事件。
一个完整的例子是:
服务器.R
library(shiny)
fakeDataProcessing <- function(duration) {
# does nothing but sleep for "duration" seconds while
# pretending some background task is going on...
Sys.sleep(duration)
}
shinyServer(function(input, output, session) {
observe({
if (input$start_proc > 0) {
fakeDataProcessing(5)
# notify the browser that the data is ready to download
session$sendCustomMessage("download_ready", list(fileSize=floor(runif(1) * 10000)))
}
})
output$data_file <- downloadHandler(
filename = function() {
paste('data-', Sys.Date(), '.csv', sep='')
},
content = function(file) {
write.csv(data.frame(x=runif(5), y=rnorm(5)), file)
}
)
})
用户界面
library(shiny)
shinyUI(fluidPage(
singleton(tags$head(HTML(
'
<script type="text/javascript">
$(document).ready(function() {
// disable download at startup. data_file is the id of the downloadButton
$("#data_file").attr("disabled", "true").attr("onclick", "return false;");
Shiny.addCustomMessageHandler("download_ready", function(message) {
$("#data_file").removeAttr("disabled").removeAttr("onclick").html(
"<i class=\\"fa fa-download\\"></i>Download (file size: " + message.fileSize + ")");
});
})
</script>
'
))),
tabsetPanel(
tabPanel('Data download example',
actionButton("start_proc", h5("Click to start processing data")),
hr(),
downloadButton("data_file"),
helpText("Download will be available once the processing is completed.")
)
)
))
在示例中,数据处理是通过等待 5 秒来伪造的。然后下载按钮就准备好了。我还在消息中添加了一些“虚假”fileSize
信息,以演示如何向用户发送额外信息。
请注意,因为 Shiny 实现actionButton
为<a>
标记而不是<button>
, 并且它在其上绑定click
事件。因此,为了完全禁用它,除了添加一个disabled
属性使其看起来被禁用之外,您还需要click
通过添加一个内联onclick
属性来覆盖它的事件。否则,用户仍然可能不小心单击(看似禁用的)下载按钮并触发下载。