问题描述
我想在 Shiny 中设计一个通知来评估输入值是否等于特定数字。以下代码示例是我的尝试。这是一个简单的应用程序,用于检查输入值是否等于 1000
。如果没有,则会显示通知。我使用 shinyalert
来创建通知,并使用 delay
包中的 shinyjs
函数来避免执行过于敏感的情况。
这个应用程序可以运行,但并不完美。问题是当用户输入一个数字时。有时它可能会多次执行通知。我相信这与用户输入数字的速度有关。例如,如果我非常快地在 numericInput 中输入 5678
,将显示一个通知,但如果我输入 56
然后非常快速地跟进 78
(在一秒内) .通知将显示两次。应用程序可能会评估 56
是否等于 1000
,然后继续测试是否 5678
等于 1000
。
如果可能,我希望我只能显示一次通知。我认为添加 delay
函数会有所帮助,但它没有,或者我没有以正确的方式使用 delay
函数。如果您有任何反馈,请告诉我。
library(shiny)
library(shinyjs)
library(shinyalert)
ui <- fluidPage(
useShinyjs(),useshinyalert(),titlePanel("Check if the input text is 1000."),numericInput(inputId = "value_in",value = 0,label = "Input value")
)
server <- function(input,output,session){
observeEvent(input$value_in,{
req(input$value_in)
delay(
ms = 2000,if (input$value_in != 1000){
shinyalert(text = "The input value is not 1000",type = "warning")
}
)
},ignoreInit = TRUE)
}
shinyApp(ui,server)
解决方法
Debounce
是要走的路。下面是关于它如何工作的更多信息,然后是一个最小的工作示例。
去抖动意味着 r
的每次失效都会在指定的时间窗口内保持。如果 r
在该时间窗口内再次失效,则计时器重新开始。这意味着只要无效在时间窗口内从 r
持续到达,去抖动的反应根本不会无效。只有在失效停止(或足够慢)后,才会发送下游失效。
library(shiny)
library(shinyjs)
library(shinyalert)
library(magrittr)
ui <- fluidPage(
useShinyjs(),useShinyalert(),titlePanel("Check if the input text is 1000."),numericInput(inputId = "value_in",value = 0,label = "Input value")
)
server <- function(input,output,session){
#Create a debounced reactive,only runs when the input has changed and then been idle for 1000 milliseconds.
value_in_debounce <- reactive(input$value_in) %>% debounce(1000)
observeEvent(value_in_debounce(),{
print(paste('Triggered at',Sys.time(),'Value is:',value_in_debounce()))
if (value_in_debounce() != 1000){
shinyalert(text = "The input value is not 1000",type = "warning")
}
},ignoreInit = TRUE)
}
shinyApp(ui,server)