【问题标题】:Update input function doesn't take affect until after observeEvent更新输入功能直到observeEvent之后才生效
【发布时间】:2018-01-23 19:33:29
【问题描述】:

按下“Test Bins”按钮应该会导致 observeEvent 函数在滑块更新后打印出 30、25 和 35,但在 updateSliderInput 之前和之后都会重复打印 30。由于某种原因,observeEvent 代码似乎没有处理滑块输入中的更改。

ui.R:

library(shiny)
shinyUI(fluidPage(
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins",
                  "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30),
      actionButton("test","Test Bins")
    ),
    mainPanel(
      plotOutput("distPlot")
    )
  )
))

服务器.R:

library(shiny)
shinyServer(function(input, output, session) {
  output$distPlot <- renderPlot({
    x    <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
  observeEvent(input$test,{
    print(input$bins)
    updateSliderInput(session,"bins",value=25)
    print(input$bins)
    updateSliderInput(session,"bins",value=35)
    print(input$bins)
  })
})

【问题讨论】:

  • input$bins 在当前observeEvent() 中没有反应。 input$bins 上的单独 observeEvent 将在点击按钮之前和之后打印值。有道理吗??

标签: r shiny


【解决方案1】:

直到observeEvent 函数结束后更改才会生效。如果您需要在观察者内部使用滑块的新值,您可以使用一个额外的变量。

在下面的示例中,您的代码已修改以显示滑块(以及相关的input$bins 变量)将如何更新,直到observeEvent 函数结束。

library(shiny)

ui <- shinyUI(fluidPage(
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins",
                  "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30),
      actionButton("test","Test Bins")
    ),
    mainPanel(
      plotOutput("distPlot")
    )
  )
))

server <- function(input, output, session){     
output$distPlot <- renderPlot({
    x    <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
  observeEvent(input$test,{
    print(input$bins)
    value  <- 25
    updateSliderInput(session,"bins",value=value)
    cat("Slider updated to:", value, "\n")
    # simulate some complex process
    Sys.sleep(1)
    cat("Observer ends\n")
  })
  observeEvent(input$bins, {
    cat("Slider changed to:", print(input$bins), "\n")
  })
}

shinyApp(ui, server)  

【讨论】:

  • 这适用于单个更新,但是如果我在 observeEvent 中有多个更新调用并且需要在每个更新调用之后打印呢?
  • 只有最后一次更新有效。更新函数只是将滑块标记为使用新值,但 Shiny 会修改滑块直到观察者结束。您可以使用多个观察者。如果您对滑块的显示更改感兴趣,可以使用一些 JavaScript。
【解决方案2】:

Geovany 的回答非常有用。我还查看了 jcheng5 的回复:https://github.com/rstudio/shiny/issues/1010,它帮助我更改了服务器,以便您可以在观察者内部使用滑块的新值,而无需添加额外的变量。服务端适配代码:

server <- function(input, output, session)
{
  output$distPlot <- renderPlot(
  {
    x    <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })

  v <- reactiveValues(bins=NULL)

  observe(
  {
    v$bins <- input$bins
  }, priority = 10)

  updateSliderValue <- function(val)
  {
    updateSliderInput(session=session, inputId="bins", value=val)
    v$bins <- val
  }

  observeEvent(input$test,{
    updateSliderValue(25)
    cat("Slider updated to:", v$bins, "\n")
    cat("Observer ends\n")
  })

  observeEvent(input$bins, {
    cat("Slider changed to:", print(v$bins), "\n")
  })
}

【讨论】:

    猜你喜欢
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    相关资源
    最近更新 更多