问题
The app below contains an actionButton
, a shinyWidgets::progressBar
and a selectInput
:
When the Start
button is clicked, an observeEvent
is triggered in which I loop through the numbers 1-10 and increment the progress bar at each iteration. I would also like to update the value of the selectInput
at each iteration but updateSelectInput does not work as expected. Instead of updating in tandem with the progress bar, the selectInput
value is only updated once the loop has terminated. I don't understand why updateProgressBar
works here but updateSelectInput
doesn't?
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
actionButton(inputId = "go", label = "Start"), #, onclick = "$('#my-modal').modal().focus();"
shinyWidgets::progressBar(id = "pb", value = 0, display_pct = TRUE),
selectInput('letters', 'choose', letters)
)
server <- function(input, output, session) {
observeEvent(input$go, {
shinyWidgets::updateProgressBar(session = session, id = "pb", value = 0) # reinitialize to 0 if you run the calculation several times
for (i in 1:10) {
updateProgressBar(session = session, id = "pb", value = 100/10*i)
updateSelectInput(session, 'letters', selected = letters[i])
Sys.sleep(.5)
}
})
}
shinyApp(ui = ui, server = server)
回答1:
It works if I set immediate = T
in removeUI
and insertUI
. I got the idea from this post - it doesn't explain why immediate = T
is needed though. According to the help page:
Immediate - whether the UI object should be immediately inserted into the app when you call insertUI, or whether Shiny should wait until all outputs have been updated and all observers have been run (default).
But I don't understand what this means in the context of the for-loop. Does it have something to do with the scope of the for-loop?
If someone could post an explanation here I will accept their answer.
Updated code:
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
actionButton(inputId = "go", label = "Start"), #, onclick = "$('#my-modal').modal().focus();"
shinyWidgets::progressBar(id = "pb", value = 0, display_pct = TRUE),
div(id = 'placeholder')
)
server <- function(input, output, session) {
observeEvent(input$go, {
shinyWidgets::updateProgressBar(session = session, id = "pb", value = 0) # reinitialize to 0 if you run the calculation several times
for (i in 1:10) {
updateProgressBar(session = session, id = "pb", value = 100/10*i)
removeUI('#text', immediate = T)
insertUI('#placeholder', ui = tags$p(id = 'text', paste('iteration:', i)), immediate = T)
Sys.sleep(1)
}
})
}
shinyApp(ui = ui, server = server)
来源:https://stackoverflow.com/questions/59799641/r-shiny-updating-the-value-of-a-selectinput-and-progressbar-simultaneously