我有一个复杂的闪亮应用程序,具有许多输入、叶片地图等等…… 我的问题是当应用程序正在进行一些计算时,用户会继续点击应用程序上的任何位置,有时应用程序会崩溃。
我希望防止用户在应用程序繁忙时进行任何点击。重要的是,旋转器保持旋转状态,而不是像“waiter”包中的整个页面等待器。也许有一种可能性将旋转器和等待器结合起来?但我还没有找出如何做到。
我在这里有一个小的reprex: 当我点击“繁忙的应用程序”按钮时,会出现一个5秒的旋转器,让用户等待。但在此期间,用户仍然可以点击“增量”按钮。在旋转器结束时,输出增加了所进行的点击次数。 我想一次性封锁整个应用程序,而不仅仅是在应用程序繁忙时在按钮上放置一个“禁用”(因为我的应用程序中有很多输入,这需要太多修改)。
我希望防止用户在应用程序繁忙时进行任何点击。重要的是,旋转器保持旋转状态,而不是像“waiter”包中的整个页面等待器。也许有一种可能性将旋转器和等待器结合起来?但我还没有找出如何做到。
我在这里有一个小的reprex: 当我点击“繁忙的应用程序”按钮时,会出现一个5秒的旋转器,让用户等待。但在此期间,用户仍然可以点击“增量”按钮。在旋转器结束时,输出增加了所进行的点击次数。 我想一次性封锁整个应用程序,而不仅仅是在应用程序繁忙时在按钮上放置一个“禁用”(因为我的应用程序中有很多输入,这需要太多修改)。
library(shiny)
ui <- fluidPage(
# spinner css
tags$head(
tags$style(HTML("
#loadmessage {
position:fixed; z-index:8; top:50%; left:50%; padding:10px;
text-align:center; font-weight:bold; color:#000000; background-color:#CCFF66;
}
.loader {
position:fixed; z-index:8; border:16px solid #999999;
border-top: 16px solid #8B0000; border-radius: 50%;
width: 120px; height: 120px; top:45%; left:45%;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}"))
),
# display load spinner when shiny is busy
conditionalPanel(
condition = "$(\'html\').hasClass(\'shiny-busy\')",
tags$div(class = "loader")
),
actionButton(
inputId = "increment",
label = "Increment"
),
textOutput("result"),
actionButton(
inputId = "busy",
label = "Busy app"
)
)
server <- function(input, output, session) {
rv <- reactiveValues(counter = 0)
#increment counter
observeEvent(input$increment,{
rv$counter = rv$counter + 1
})
#display incremented counter
output$result <- renderText({
rv$counter
})
observeEvent(input$busy, {
Sys.sleep(5)
# during this time, the user should not be able to do anything on the app
})
}
shinyApp(ui = ui, server = server)