即使条件未更改,也会在Shiny中触发observeEvent

ijnw1ujt  于 2023-03-10  发布在  其他
关注(0)|答案(2)|浏览(141)

由于observeEvent的工作方式(通常非常直观),我在应用程序中获得我所寻找的功能时遇到了一些麻烦。
我正在寻找的基本功能是,用户可以输入几个数字,点击“提交”,然后弹出一个模态来获取用户的姓名。之后,应用程序记录姓名并对数字求和,然后清除输入。然后我希望用户能够使用相同的名称重复该过程-但目前的应用程序结构使得sums使用observeEvent,仅当名称不同时才响应(即,连续两次使用相同的名称是不起作用的,虽然我希望它这样做)。您可以在应用程序中看到,我尝试的解决方案是重置inputSweetAlert的输入(使用shinyjs),但它不能访问它,我猜是因为它实际上不在UI端。我正在使用shinyWidgets sweetAlerts,我想继续这样做。
下面是一个示例应用程序:

library("shiny")
library("shinyWidgets")
library("shinyjs")

ui <- fluidPage(
  shinyjs::useShinyjs(),
  numericInput("num1", "Enter a number", value=NULL),
  numericInput("num2", "Enter another number", value=NULL),
  actionButton(inputId = "go", label = "submit"),
  verbatimTextOutput(outputId = "res1"),
  verbatimTextOutput(outputId = "res2")
)

server <- function(input, output, session) {

  observeEvent(input$go, {
    inputSweetAlert(session = session, inputId = "name", title = "What's your name?")
  })

  x <- reactiveValues(val=NULL)

  observeEvent(input$name, {
    x$val <- input$num1 + input$num2
    confirmSweetAlert(session = session, inputId = "confirmed", title = "Success!", text = "Your responses have been recorded. All is in order.", type = "success", btn_labels = c("Ok, let me continue")
    )
  })

  ## A possible approach to a solution...
  observeEvent(input$confirmed, {
    shinyjs::reset("num1") 
    shinyjs::reset("num2") 
    shinyjs::reset("name")
  })

  output$res1 <- renderPrint(paste("Name:", input$name))
  output$res2 <- renderPrint(paste("Sum:", x$val))
}

shinyApp(ui = ui, server = server)

谢谢你能提供的任何帮助!

1l5u6lss

1l5u6lss1#

您可以通过JS重置input$name

runjs('Shiny.setInputValue("name", null, {priority: "event"});')

下面是一个工作示例:

library("shiny")
library("shinyWidgets")
library("shinyjs")

ui <- fluidPage(
  shinyjs::useShinyjs(),
  numericInput("num1", "Enter a number", value = NULL),
  numericInput("num2", "Enter another number", value = NULL),
  actionButton(inputId = "go", label = "submit"),
  verbatimTextOutput(outputId = "res1"),
  verbatimTextOutput(outputId = "res2")
)

server <- function(input, output, session) {
  
  observeEvent(input$go, {
    inputSweetAlert(session = session, inputId = "name", title = "What's your name?")
    runjs('Shiny.setInputValue("name", null, {priority: "event"});')
  })
  
  x <- reactiveValues(val = NULL)
  
  observeEvent(input$name, {
    x$val <- input$num1 + input$num2
    confirmSweetAlert(session = session, inputId = "confirmed", title = "Success!", text = "Your responses have been recorded. All is in order.", type = "success", btn_labels = c("Ok, let me continue"))
  })
  
  observeEvent(input$confirmed, {
    shinyjs::reset("num1") 
    shinyjs::reset("num2") 
    shinyjs::reset("mytext")
  })
  
  output$res1 <- renderPrint(paste("Name:", input$name))
  output$res2 <- renderPrint(paste("Sum:", x$val))
}

shinyApp(ui = ui, server = server)

有关详细信息,请参阅此article

**EDIT:**在使用模块的应用中,可以像这样修改对runjs()的调用,以便命名id:

runjs(paste0("Shiny.setInputValue(\"", ns("name"), "\", null, {priority: \"event\"});"))
4nkexdtk

4nkexdtk2#

这里有一个变通方法,就是在每次点击按钮时更改输入ID。

library("shiny")
library("shinyWidgets")
library("shinyjs")

ui <- fluidPage(
  shinyjs::useShinyjs(),
  numericInput("num1", "Enter a number", value=NULL),
  numericInput("num2", "Enter another number", value=NULL),
  actionButton(inputId = "go", label = "submit"),
  verbatimTextOutput(outputId = "res1"),
  verbatimTextOutput(outputId = "res2")
)

server <- function(input, output, session) {

  go <- reactive({
    input$go
  })

  observeEvent(input$go, {
    inputSweetAlert(session = session, inputId = sprintf("name-%d", go()), 
                    title = "What's your name?")
  })

  x <- reactiveValues(val=NULL)

  observeEvent(input[[sprintf("name-%d", go())]], {
    x$val <- input$num1 + input$num2
    confirmSweetAlert(session = session, inputId = "confirmed", title = "Success!", text = "Your responses have been recorded. All is in order.", type = "success", btn_labels = c("Ok, let me continue")
    )
  })

  ## A possible approach to a solution...
  observeEvent(input$confirmed, {
    shinyjs::reset("num1") 
    shinyjs::reset("num2") 
    shinyjs::reset("mytext")
  })

  output$res1 <- renderPrint(paste("Name:", input[[sprintf("name-%d", go())]]))
  output$res2 <- renderPrint(paste("Sum:", x$val))
}

shinyApp(ui = ui, server = server)

相关问题