如何在Shiny中设计一个通知系统来评估输入值?

How to design a notification system in Shiny to evaluate the input value?

我想在 Shiny 中设计一个通知来评估输入值是否等于特定数字。下面的代码示例是我的尝试。这是一个简单的应用程序,用于检查输入值是否等于 1000。如果没有,将显示一条通知。我使用 shinyalert 创建通知和 shinyjs 包中的 delay 函数以避免执行过于敏感的情况。

此应用程序有效但不完美。问题是当用户输入数字时。有时它可能会多次执行通知。我相信这与用户输入数字的速度有关。例如,如果我在 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 是要走的路。下面是关于它如何工作的更多信息,然后是一个最小的工作示例。

Debouncing means that every invalidation from r will be held for the specified time window. If r invalidates again within that time window, then the timer starts over again. This means that as long as invalidations continually arrive from r within the time window, the debounced reactive will not invalidate at all. Only after the invalidations stop (or slow down sufficiently) will the downstream invalidation be sent.

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)