Shiny withProgress进度条关闭图标隐藏及点击状态检测咨询
解决Shiny进度条关闭按钮导致UI无响应问题
方案1:直接隐藏关闭按钮(最简实现)
你提到的style="old"参数确实可以直接禁用关闭按钮,如果你想保留新版进度条的样式,也可以通过全局CSS隐藏所有进度通知的关闭按钮,只需要在UI的dashboardBody开头添加如下代码即可:
shiny::tags$head( shiny::tags$style(HTML(" .shiny-notification-close { display: none !important; } ")) )
该方案不需要修改业务逻辑,适合不需要取消功能的场景。
方案2:实现点击关闭按钮取消长耗时任务
你之前的JS代码失效是因为事件绑定的时候进度条还没有渲染到页面上,动态生成的元素无法直接绑定点击事件,需要把事件委托到全局的document对象上,同时需要把长耗时任务改成可中断的模式,具体修改如下:
步骤1:UI引入shinyjs并添加事件监听
首先在UI的dashboardBody里添加shinyjs初始化和事件监听代码:
body=shinydashboard::dashboardBody( shinyjs::useShinyjs(), # 初始化shinyjs shiny::tags$script(HTML(" // 把关闭按钮点击事件委托到document,适配动态生成的进度条 $(document).on('click', '.shiny-notification-close', function() { Shiny.setInputValue('pb_close_click', Math.random()); // 用随机值保证每次点击都能触发R端响应 }); ")), # 其余原有UI代码不变 )
步骤2:修改长耗时函数支持中断
给long_run_op增加一个检查取消状态的回调参数:
long_run_op <- function(num_iter, verbose=TRUE, cancel_check = function(){FALSE}) { for (x in 1:num_iter) { # 每次循环先检查是否触发了取消 if(cancel_check()) { if(verbose) message("task cancelled by user.") return(NULL) } if(verbose) message("working... [value=",x,"]") Sys.sleep(0.5) } if(verbose) message("calculation finished.") return(rnorm(num_iter)) }
步骤3:修改server逻辑支持取消
server <- function(input, output, session) { # 存储任务取消状态 task_cancelled <- shiny::reactiveVal(FALSE) # 监听关闭按钮点击事件 shiny::observeEvent(input$pb_close_click, { task_cancelled(TRUE) }) shiny::observeEvent(input$run, { # 每次运行前重置取消状态 task_cancelled(FALSE) shiny::withProgress( withCallingHandlers( out <- long_run_op( num_iter=input$num_iter, verbose=TRUE, # 传入取消检查函数 cancel_check = function() task_cancelled() ), message=function(m) if(grepl("\\[value=[0-9]+\\]", m$message)) { val <- as.numeric(gsub(".*\\[value=([0-9]+)\\].*$", "\\1", m$message)) shiny::setProgress(value=val) } ), message="working...", max=input$num_iter, value=0 ) # 只有任务没取消的时候才渲染结果 if(!is.null(out)) { output$result <- shiny::renderPlot(plot(out)) } else { # 可以加个提示告知用户任务已取消 shiny::showNotification("任务已被取消", type = "warning") } }) }
该方案既保留了进度条的关闭按钮,又能实现用户主动取消长耗时任务,避免UI假死。
内容的提问来源于stack exchange,提问作者Karsten W.
相关产品推荐
相关产品推荐

