使用reactValues从observeEvent中的for循环更新闪亮的输出

时间:2019-09-26 21:49:40

标签: r shiny

我正在尝试使用reactiveValues中的更改从循环内部更新uiOutput,但似乎不起作用。 我已经研究了一些答案,但是他们都在尝试从output $ somthing内部进行操作,但实际情况并非如此: 像那些:

Update shiny output within loop

For loop inside output in Shiny

这里有一些可复制的应用程序。

vars = reactiveValues(cc="",ct=0)
ui = fluidRow(uiOutput("warngt"),actionButton("searchgt","Search"))
server = function(input, output, session){
  observeEvent(input$searchgt,{
    if(vars$ct<10){
      repeat{
        vars$ct=vars$ct+1
        vars$cc=paste(sprintf('<b style="color:blue">',"Searching...[%s]",vars$ct),"</b>");Sys.sleep(.5)
        #This also does not work:
        #output$warngt=renderUI({HTML(vars$cc)})
        vars$busca = try(print("Something"),silent = T)
        if(vars$ct==10){break}
      }
    }else{
      #This work just fine
      vars$cc=paste('<b style="color:red">',"Some warning.","</b>")
    }
    #This also doesn't work
    #output$warngt=renderUI({HTML(vars$cc)})
  })
  output$warngt = renderUI({HTML(vars$cc)})
}
shinyApp(ui = ui, server = server)

谢谢!

1 个答案:

答案 0 :(得分:1)

我重写了您的服务器代码以使其正常工作。

您不能像我在评论中提到的那样循环更新UI,这不是Shiny的工作原理。使用invalidateLater()进行类似于for循环的操作。

而且,invalidateLater()observeEvent中不起作用,因此您需要在observe()中编写循环逻辑

isolate()用于防止观察者递归触发,因此它仅基于invalidateLater(500)

每0.5秒重新评估一次
server = function(input, output, session){
  vars = reactiveValues(cc="",ct=0)
  startSearch <- reactiveVal(FALSE)
  startSearch <- eventReactive(input$searchgt,{
    TRUE
  })

  observe({
    req(startSearch())
    if (isolate(vars$ct) < 10){
      invalidateLater(500)
      isolate({
        vars$ct=vars$ct+1
        vars$cc=paste('<b style="color:blue">',"Searching...",vars$ct,"</b>")
        vars$busca = try(print("Something"),silent = T)
      })
    } else {
      vars$cc=paste('<b style="color:red">',"Some warning.","</b>")
    }

  })

  output$warngt = renderUI({HTML(vars$cc)})
}