我正在尝试使用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)
谢谢!
答案 0 :(得分:1)
我重写了您的服务器代码以使其正常工作。
您不能像我在评论中提到的那样循环更新UI,这不是Shiny的工作原理。使用invalidateLater()
进行类似于for循环的操作。
而且,invalidateLater()
在observeEvent
中不起作用,因此您需要在observe()
中编写循环逻辑
isolate()
用于防止观察者递归触发,因此它仅基于invalidateLater(500)
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)})
}