在闪亮的应用程序中单击下载按钮后,将打开一个新页面以初始化下载。但是,我的下载处理程序需要一些时间来生成可下载文件,该文件显示在主闪亮页面的进度条中。有没有办法让用户保持在主页面上或阻止下载页面打开或推迟下载页面直到文件生成?
非常感谢
马库斯
答案 0 :(得分:6)
Vincent的解决方案使用了两个按钮,一个用于计算的动作按钮和一个用于下载的下载按钮。此解决方案的另一个好处是进度条也包含在shinyIncubator包中。
对我的代码的解释会让其他人想要做同样的事情:
ui.R有一个动作按钮和一个动态下载按钮:
actionButton("makePlots", "Calculate Results"),
uiOutput("download_button")
进度条的进度初始化:
mainPanel(
progressInit(),
uiOutput("mytabs")) # dynamic rendering of the tabs
server.R有点复杂。因此只有在有东西需要下载时才显示下载按钮我使用动态uiOutput并使用以下代码:
output$download_button <- renderUI({
if(download){
downloadButton("downloadPlots", "Download Results")
}
})
下载按钮仅在download==TRUE
时显示。在server.R的开头,变量初始化为:download<-FALSE
当每次单击动作按钮时动作按钮增加1,我包含一个计数器(初始值0),在每次“使用”动作按钮后增加。原因是第一个if语句。
makePlots<-reactive({
if(input$makePlots>counter){ # tests whether action button has been clicked
dir.create("new_directory_for_output")
withProgress(session, min=1, max=15, expr={ # setup progress bar
for(i in 1:15){
png(paste0("new_directory_for_output/plot",i,".png"))
plot(i)
dev.off()
setProgress(message = 'Calculation in progress',
detail = 'This may take a while...',
value=i)
} # end for
}) # end progress bar
counter<<-counter+1 # needs the <<- otherwise the value of counter
# is only changed within the function
download<<-TRUE # something to download
} # end if
}) # end function
在此阶段,函数makePlots()没有输出,并且不会在任何地方调用,因此它什么都不做。因此,我将makePlots()放在每个标签的开头,这样无论用户在哪个标签上,一旦点击了操作按钮,就会制作并保存图表。
最后一块拼图是下载处理程序:
output$downloadPlots <- downloadHandler(
filename = function() { my_filename.zip },
content = function(file){
fname <- paste(file,"zip",sep=".")
zip(fname,new_directory_for_output) # zip all files in the directory
file.rename(fname,file)
unlink(new_directory_for_output,recursive = TRUE) # delete temp directory
download<<-FALSE # hide download button
}
) # end download handler
答案 1 :(得分:4)
以下是为downloadHandler
输出生成的html代码示例:
<a id="downloadData" class="btn shiny-download-link shiny-bound-output" target="_blank" href="session/d832cc1f9218bd9e356572b089628030/download/downloadData?w=">Download</a>
target属性指定打开href的位置,target="_blank"
在新选项卡或新窗口中打开它。
默认情况下(在许多浏览器上)当你打开一个新标签时它会聚焦它,这是你想要避免的,问题是你不能用一些HTML / JS改变客户端的默认行为。
此外,更改为target="self"
会在点击相同的框架中打开href网址,但问题是它会关闭当前会话并且您需要打开此会话(带有{{1的标签) } url)下载数据。
尽管如此,您可以添加一个非令人不安的注释,用户可以使用Ctrl + Click打开下载,而无需关注新的空标签。
例如:
localhost:port