这是一个简单而先进的问题.这是一个演练:
我有三个输入i_1,i_2,i_3,它们导致三个在不同功能中使用的无功值:
I1 <- reactive({input$i_1})
I2 <- reactive({input$i_2})
I3 <- reactive({input$i_3})
Run Code Online (Sandbox Code Playgroud)
具体来说,这三个值用于将图形绘制为反应性端点:
output$plot <- renderPlot {(
plot( f(I1(), I2(), I3()) )
)}
Run Code Online (Sandbox Code Playgroud)
闪亮的魔法工作,一切正常,直到我想加载一些数据并修改三个i_X值:
observe {(
input$b_Load #Load button
[...]
updateSelectInput(session,"i_1", value = 4)
updateSelectInput(session,"i_2", value = 3)
updateSelectInput(session,"i_3", value = 5)
...
)}
Run Code Online (Sandbox Code Playgroud)
更新本身工作正常,变量的三个新值将发送到客户端.
问题:然后更新这些值并逐个发送回服务器,每次不必要地重新计算图形.当所有值都更新时,我只想更新一次图表.可能吗?
我试图等待onFlushed事件:
values <- reactiveValues(loadingProfile = FALSE)
session$onFlushed(function() {
values$loadingProfile <- FALSE
cat("##### DEBUG: loading Profile OFF ##############\n", file = stderr())
}, once = FALSE)
output$plot <- renderPlot {(
if (!values$loadingProfile) {
plot( f(I1(), I2(), I3()) )
}
)}
observe {(
input$b_Load #Load button
values$loadingProfile <- TRUE #Toggle on the watching value
cat("##### DEBUG: loading Profile ON ##############\n", file = stderr())
[...]
updateSelectInput(session,"i_1", value = 4)
updateSelectInput(session,"i_2", value = 3)
updateSelectInput(session,"i_3", value = 5)
...
)}
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为每次将三个更新版本中的一个发送回服务器时刷新会话...(我在激活跟踪后检查了控制台)
什么不能正常工作:
updateSelectInput()以前相同,则不会发回该值.invalidateLater(2000, session)有点作品(我试过),但不健壮.不可能指定一个总是捕获不同交换而没有超调的时间,从而暂停执行太长时间.根据我对 Shiny 当前状态的了解,这个问题本身没有答案。尽管如此,使用很棒的reactive()表达式,我已经能够重构值流并仅更新图形一次。事实上
output$plot <- renderPlot {(
plot( f(User()) )
)}
observe {(
input$b_Load #Load button
updateSelectInput(session,"i_1", value = 4)
updateSelectInput(session,"i_2", value = 3)
updateSelectInput(session,"i_3", value = 5)
...
)}
User <- reactive({
object <- list()
object$i1 <- I1()
object$i2 <- I2()
object$i3 <- I3()
)}
Run Code Online (Sandbox Code Playgroud)
+ 的一个小重写f()。
在这里,User()反应式表达式扮演了缓冲区的角色。它将等待所有先前的更改被推送,然后再将其自己的值发送到f()。
我已在Github上分享了完整的 Shiny 项目,以获取更多信息。