即使条件没有改变,也可以在Shiny中触发observeEvent

时间:2019-09-15 17:45:58

标签: r shiny shinyjs shinywidgets

由于observeEvent的工作方式(通常非常直观),我在寻找所需的应用程序功能时遇到了一些麻烦。

我要寻找的基本功能是用户可以输入几个数字,单击“提交”,然后弹出一个模态以使用用户名。之后,该应用会记录名称并对数字求和,然后清除输入。然后,我希望用户能够使用相同的名称重复该过程-但应用程序当前已结构化,因此总和使用observeEvent仅在名称不同(即使用相同的名称)时才响应连续两次不起作用,尽管我希望这样做)。您可以在应用程序中看到,我尝试的解决方案是重置inputSweetAlert的输入(使用shinyjs),但是我无法访问它,因为它实际上不在用户界面上侧。我正在使用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)

感谢您提供的任何帮助!

2 个答案:

答案 0 :(得分:2)

您可以通过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

答案 1 :(得分:2)

这是一种解决方法。这个想法是在每次单击按钮时更改输入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)