RShiny 中的反应性输入反应太快(不使用按钮)

Reactive input in RShiny reacts too quickly (without using a button)

如何让 Shiny 等待用户输入他们的邮政编码(不使用按钮)。我面临的问题是,如果用户输入邮政编码的速度不够快,它会很快跳转到错误。 编辑:

library(shiny)

shinyApp(ui <- fluidPage(sidebarPanel(
  "",
  textInput("zipcode", label = "Enter your zipcode.", value = 98125)
  
)) ,


server <- function(input, output, session) {
  observeEvent(input$zipcode, {
    #limits zipcode input to 5 numbers only
    if (nchar(input$zipcode) != 5)
    {
      updateTextInput(session, 'zipcode', value = 98125)
      showModal(
        modalDialog(
          title = "Error!",
          "Only 5-character entries are permitted.",
          easyClose = TRUE
        )
      )
    }
    if (is.na(as.numeric(input$zipcode)))
    {
      showModal(
        modalDialog(
          title = "Error!",
          "Only numeric values are allowed. Please try again.",
          easyClose = TRUE
        )
      )
    }
  })
})

添加了 JS 代码,input$keyPressed 在任意位置按下“Return”键时接收一个随机数。

library(shiny)

js <- '
$(document).on("keyup", function(e) {
  if(e.keyCode == 13){
    Shiny.onInputChange("keyPressed", Math.random());
  }
});
'

shinyApp(ui <- fluidPage(tags$script(js),
                         sidebarPanel(
                           "",
                           textInput("zipcode", label = "Enter your zipcode.", value = 98125),
                           textOutput("zip")
                         )) ,
         
         server <- function(input, output, session) {
           observeEvent(input[["keyPressed"]], {
             #limits zipcode input to 5 numbers only
             if (nchar(input$zipcode) != 5)
             {
               updateTextInput(session, 'zipcode', value = 98125)
               showModal(
                 modalDialog(
                   title = "Error!",
                   "Only 5-character entries are permitted.",
                   easyClose = TRUE
                 )
               )
             }
             if (is.na(as.numeric(input$zipcode)))
             {
               showModal(
                 modalDialog(
                   title = "Error!",
                   "Only numeric values are allowed. Please try again.",
                   easyClose = TRUE
                 )
               )
             }
             output$zip <- renderText(input$zipcode)
           })
         })

链接到:

你可以使用 debounce:

This lets you ignore a very "chatty" reactive expression until it becomes idle, which is useful when the intermediate values don't matter as much as the final value

您不需要 Sys.sleep,它会在触发反应之前等待 millis 毫秒:

library(shiny)

shinyApp(
  ui <- fluidPage( 
    sidebarPanel("", textInput("zipcode", label="Enter your zipcode.", value = 98125)
                 
    )  ) , 
  
  
  server <- function(input, output, session) {
    zipcode <- reactive(input$zipcode)
    zipcode_d <- debounce(zipcode, millis = 2000)
    observeEvent(zipcode_d(),{     #limits zipcode input to 5 numbers only
      if(nchar(zipcode_d())!=5)
      {
        updateTextInput(session,'zipcode',value=98125)
        showModal(modalDialog(
          title = "Error!",
          "Only 5-character entries are permitted.",
          easyClose = TRUE
        ))
      }
      if(is.na(as.numeric(zipcode_d())))
      {
        showModal(modalDialog(
          title = "Error!",
          "Only numeric values are allowed. Please try again.",
          easyClose = TRUE
        ))
      }
    }
    )
  })