在invalidatelater观察器内部增加反应值

时间:2019-01-25 11:43:29

标签: r shiny invalidation

我正在尝试构建Shinyapp,以进行非常简单的测验。我有一个包含10个问题的data.frame,用户单击以回答0或1。 它一直有效,直到我尝试实现定时器/ 倒数,以便使用i调用在5秒后自动出现下一个问题。

当前问题编号存储在reactValues()对象的变量init = data.frame(question=paste("question", 1:10), correct=c(1,1,1,1,1,0,0,0,0,0), answer=NA, stringsAsFactors = FALSE) library(shiny); library(shinydashboard) ui=dashboardPage(dashboardHeader(title = "questionnaire"),dashboardSidebar(),dashboardBody( fluidRow(box(width = 6, title="how it works..", p("balblabla"))), fluidRow( box(width = 12, background = "orange", fluidRow( box(width = 12, verbatimTextOutput("question"), tags$head(tags$style("#question{font-size: 20px; text-align: left; font-weight: bold;}")) ), box(width = 12, actionButton("negative", "answer 0", width = '30%'), actionButton("positive", "answer 1", width = '30%') )))))) server <- function(input, output, session) { vals = reactiveValues(df = init, i=1) output$question <- renderText({vals$df[vals$i, "question"]}) observe({ invalidateLater(5000) vals$i <- vals$i + 1 }) observeEvent(input$negative, ignoreInit=TRUE, { vals$df[vals$i, "answer"] = 1 if (vals$df[vals$i, "correct"]==1){ showNotification("WRONG!", type="error", duration=1, closeButton = FALSE) } else { showNotification("CORRECT!", type="message", duration=1, closeButton = FALSE) }}) observeEvent(input$positive, ignoreInit=TRUE, { vals$df[vals$i, "answer"] = 1 if (vals$df[vals$i, "correct"]==0){ showNotification("WRONG!", type="error", duration=1, closeButton = FALSE) } else { showNotification("CORRECT!", type="message", duration=1, closeButton = FALSE) }}) } shinyApp(ui, server)

当我添加观察功能时,该应用程序停止工作并且没有显示问题。我的代码在这里:

re.match

您能帮我解决此观察声明吗,我不知道这里出了什么问题。

1 个答案:

答案 0 :(得分:1)

您需要isolate在该观察者中的索引增量:

  observe({
    invalidateLater(5000)
    vals$i <- vals$i + 1
  })

,否则将以无限循环的方式发送它,因为它在观察者内部更改了“观察到的”值,从而无论触发时间如何,都会不断触发重新评估(您可以通过添加{{1}来进行验证}在当前代码中位于观察者末尾的指令。

所以,类似的东西似乎可以工作:

print(vals$i)

请注意,我将 vals = reactiveValues(df = init, i=0) output$question <- renderText({vals$df[vals$i, "question"]}) observe({ invalidateLater(5000) isolate(vals$i <- vals$i + 1) }) 的初始化更改为零,以避免在初始化时跳过一个问题。

HTH。