1

我的网页中有一个actionButton()进行一些计算的程序,它会在 20 或 30 秒后完成。

有没有办法在应用程序运行时禁用按钮?或者任何其他方法也可能很有趣。我问这个是因为我的应用程序的一些用户双击了actionButton,我可以在服务器中看到计算运行了两次。

谢谢!

4

2 回答 2

7

您可以在几乎所有带有 package.json 功能的输入上使用禁用功能shinyjs。下面我创建了一些密集的操作,并且该按钮将在生成表格时停用,因此除非首先生成输出,否则用户不能多次按下它。

rm(list = ls())
library(shiny)
library(DT)
library(shinyjs)

ui =fluidPage(
  useShinyjs(),
  sidebarPanel(
    sliderInput("numbers", "Number of records", 1000000, 5000000, 1000000, sep = ""),
    actionButton("goButton","GO")
  ),
  mainPanel(DT::dataTableOutput('table'))
)

server = function(input, output, session){

  My_Data<-reactive({
    if (is.null(input$goButton) || input$goButton == 0){return()}
    isolate({
      input$goButton
      # Disable a button
      disable("goButton")
      # below is your intensive operation
      a <- round(rnorm(input$numbers),2)
      b <- round(rnorm(input$numbers),2) 
      # Enable a button again
      enable("goButton")
      data.frame("a" = a, "b" = b)
    })
  })

  output$table <- DT::renderDataTable(withProgress(datatable(My_Data(),options = list(searching = FALSE,pageLength = 10,lengthMenu = c(5,10, 50))),message = "Generating Data"))
}
runApp(list(ui = ui, server = server))
于 2015-09-16T11:14:21.077 回答
5

您可以在单击按钮后禁用按钮并在退出时再次启用它。它可以手动完成,但shinyjs已经提供了所需的帮助程序。

如果单击时调用的函数可能会失败,您可以使用tryCatchwithfinally来确保您的应用不会停留在禁用状态:

library(shiny)
library(shinyjs)

foo <- function() {
    Sys.sleep(4)
    x <- runif(1)
    if(x < 0.5) stop("Fatal error")
    print(x)
}

shinyApp(
    ui=shinyUI(bootstrapPage(
        useShinyjs(),
        actionButton("go", "GO")
    )),
    server=shinyServer(function(input, output, session){
        observe({
            if(input$go == 0) return()
            shinyjs::disable("go")

            tryCatch(
                foo(),          
                error = function(e) return(),
                finally = shinyjs::enable("go")
            )
        })
    })
)
于 2015-09-16T11:14:16.633 回答