在 invalidatelater 观察者内部增加反应值
increment reactivevalue inside invalidatelater observer
我正在尝试构建 shinyapp 来做一个非常简单的测验。我有一个包含 10 个问题的 data.frame,用户点击回答 0 或 1。
它一直有效,直到我尝试实现 timer / countdown 以便下一个问题在 5 秒后自动出现,使用 invalidateLater()
调用.
当前题号存储在一个reactiveValues()对象中,变量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)
你能帮我修正这个观察语句吗,我不知道这里出了什么问题。
您需要isolate
此观察者内索引的增量:
observe({
invalidateLater(5000)
vals$i <- vals$i + 1
})
,否则你将在无限循环中发送它,因为它 "observes" 的值在观察者内部发生了变化,不断触发重新评估,而不管经过的时间如何(你可以通过添加一个来验证这一点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.
我正在尝试构建 shinyapp 来做一个非常简单的测验。我有一个包含 10 个问题的 data.frame,用户点击回答 0 或 1。
它一直有效,直到我尝试实现 timer / countdown 以便下一个问题在 5 秒后自动出现,使用 invalidateLater()
调用.
当前题号存储在一个reactiveValues()对象中,变量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)
你能帮我修正这个观察语句吗,我不知道这里出了什么问题。
您需要isolate
此观察者内索引的增量:
observe({
invalidateLater(5000)
vals$i <- vals$i + 1
})
,否则你将在无限循环中发送它,因为它 "observes" 的值在观察者内部发生了变化,不断触发重新评估,而不管经过的时间如何(你可以通过添加一个来验证这一点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.