инкремент реактивного значения внутри наблюдателя инвалида - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь построить Shinyapp, чтобы сделать очень простой тест. У меня есть data.frame с 10 вопросами, и пользователь нажимает, чтобы ответить 0 или 1. Это работало до тех пор, пока я не попытался реализовать таймер / обратный отсчет , чтобы следующий вопрос появлялся автоматически через 5 секунд, используя вызов invalidateLater().

Текущий номер вопроса хранится в объекте реактивного типа (), переменная i

Когда я добавил свою функцию наблюдения, приложение перестало работать и не отображало вопрос. Мой код здесь:

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)

Можете ли вы помочь мне исправить это замечание, я не знаю, что здесь не так.

1 Ответ

0 голосов
/ 27 января 2019

Вам необходимо isolate приращение индекса в этом наблюдателе:

  observe({
    invalidateLater(5000)
    vals$i <- vals$i + 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)
  })

Обратите внимание, что я изменил инициализацию i на ноль, чтобы не пропускать вопрос при инициализации.

HTH.

...