我在Shiny应用程序中使用rhandsontable
包,该应用程序应具有以下功能:
actionButton
调用(以及应用启动时)以下应用程序完全符合我的要求,但我无法弄清楚如何摆脱全局变量did_recalc
。这是一个最小的例子,其中数据由两个总结的数值组成。
library(shiny)
library(rhandsontable)
did_recalc <- FALSE
ui <- fluidPage(
rHandsontableOutput('table'),
textOutput('result'),
actionButton("recalc", "generate new random vals and calculate")
)
server <- function(input,output,session)({
dataset_generator <- eventReactive(input$recalc, {
df <- as.data.frame(runif(2))
output$table <- renderRHandsontable({rhandsontable(df)})
did_recalc <<- TRUE
df
}, ignoreNULL = FALSE)
output$result <- renderText({
df <- dataset_generator()
if (!is.null(input$table) && !did_recalc)
df <- hot_to_r(input$table)
did_recalc <<- FALSE
sum(df)
})
})
shinyApp(ui = ui, server = server)
如果删除!did_recalc
中的output$result <- ...
条件,则编辑表仍会调用(正确)计算。但如果&#34; recalc&#34;被按下(完成一些手动编辑后),然后&#34; recalc&#34;按钮只生成新的随机值,但不重新计算总和。
在我看来,input$table
可以通过手动编辑表对象来改变,而不关心通过renderRHandsontable
给出的新值。因此,我需要使用全局变量进行此操作,这样我就可以跟踪用户是否只是重新生成数据(导致input$table
过时&#34;过时&#34;)
有没有人知道如何在没有全局变量的情况下获得此示例的功能?
答案 0 :(得分:15)
您可以将数据存储在reactiveValues
中,并让两个观察者更新它;如果单击该按钮,则为一个,如果手动编辑该表,则为一个。
在output$table
和output$result
中,您只需要使用reactiveValues
中的数据。这是一个示例(与您发布的ui.R
相同):
server <- function(input,output,session)({
values <- reactiveValues(data=as.data.frame(runif(2)))
observe({
input$recalc
values$data <- as.data.frame(runif(2))
})
observe({
if(!is.null(input$table))
values$data <- hot_to_r(input$table)
})
output$table <- renderRHandsontable({
rhandsontable(values$data)
})
output$result <- renderText({
sum(values$data)
})
})