-->

Pattern for triggering a series of Shiny actions

2019-07-30 00:09发布

问题:

I'm having trouble creating a sequence of events in a Shiny app. I know there are other ways of handling parts of this issue (with JS), and also different Shiny functions I could use to a similar end (e.g. withProgress), but I'd like to understand how to make this work with reactivity.

The flow I hope to achieve is as follows: 1) user clicks action button, which causes A) a time-consuming calculation to begin and B) a simple statement to print to the UI letting the user know the calculation has begun 2) once calculation returns a value, trigger another update to the previous text output alerting the user the calculation is complete

I've experimented with using the action button to update the text value, and setting an observer on that value to begin the calculation (so that 1B runs before 1A), to ensure that the message isn't only displayed in the UI once the calculation is complete, but haven't gotten anything to work. Here is my latest attempt:

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      actionButton("run", "Pull Data")
    mainPanel(
      textOutput("status")
    )
  )
)


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

  # slow function for demonstration purposes...
  test.function <- function() {
    for(i in seq(5)) {
      print(i)
      Sys.sleep(i)
    }
    data.frame(a=c(1,2,3))
  }

  report <- reactiveValues(
    status = NULL,
    data = NULL
    )

  observeEvent(input$run, {
    report$status <- "Pulling data..."
  })

  observeEvent(report$status == "Pulling data...", {
      report$data <- test.function()
  })

  observeEvent(is.data.frame(report$data), {
      report$status <- "Data pull complete"
    }
  )

  observe({
    output$status <- renderText({report$status})
  })
}

Eventually, I hope to build this into a longer cycle of calculation + user input, so I'm hoping to find a good pattern of observers + reactive elements to handle this kind of ongoing interaction. Any help is appreciated!