闪亮的反应对象逻辑问题

Shiny reactive objects logic issue

我的目标是实现一个闪亮的应用程序,它向用户显示几个“问题”以及可能的答案列表,然后让用户选择一个答案并将其存储。每个问题都有一个用户可以覆盖的先前存储的答案。

我找不到用反应对象同时满足这两个约束的方法:

下面是显示我当前尝试的简化代码(无数据,无 loading/writing)。在此版本中,问题是当 selected 新问题时,会立即写入上一个问题的 selected 答案。


library(shiny)

maxProblem=10

ui <- fluidPage(
  
  titlePanel("Debugging test"),
  fluidRow(
    column(12,
           verbatimTextOutput("nbProblems"),
           uiOutput("ProblemSelection"),
           uiOutput("answerSelection")
    )
  )
)



server <- function(input, output) {
  
  

  output$ProblemSelection <- renderUI({
    numericInput("ProblemSelectionNo", 
                 "Select Problem no", 
                 value = 1, min=1, max=maxProblem)
  })
  
  
  currentProblemData <- reactive({
    print("calling loadCurrentProblemData")
    if (!is.null(input$ProblemSelectionNo)) {
      print("pretending to load data and previously stored answer for problem", input$ProblemSelectionNo)
      list( choices=c(1,2,3), answer=1)
    }
  })

    output$answerSelection <- renderUI({
    l<-currentProblemData()
    choicesList <- l$choices
    names(choicesList) <- l$choices
    radioButtons("answerInput", label = "Select answer",
                 choices = choicesList, 
                 selected = l$answer)
  })
  

  writeChanges <- observe({
    print('calling writeChanges')
    l<-currentProblemData()
    newAnswer <- input$answerInput
    prevAnswer <- l$answer
    if (!is.null(prevAnswer) && !is.null(newAnswer) && (newAnswer != prevAnswer)) {
      print(paste('Pretending to write new answer :',newAnswer,'for problem', input$ProblemSelectionNo))
      l$answer <- newAnswer
    }

  })

  
}

# Run the application 
shinyApp(ui = ui, server = server)

这可能具有您正在寻找的功能。我做了一个可行的例子来尝试基于你所拥有的一些东西。

首先,我创建了一个默认列表choices_answer,可以灵活地存储您的默认问题选择和答案。 reactiveValues 列表 lst (rv$lst) 将以此开头,然后随着选择新答案而改变以存储新响应。

当通过 numericInput 选择新问题时,radioButtons 会根据该问题的当前答案更新(使用 rv$lst)。 Likewise, when a new answer is chosen (or answer is changed), the rv$lst will be updated with the new answer for storage.

我还添加了输出 ListData 以显示当您使用单选按钮进行选择时答案的存储方式。

library(shiny)

maxProblem = 5

choices_answer = list()
for (i in seq_along(1:maxProblem)) {
  choices_answer[[i]] <- list(
    choices = c("1", "2", "3"),
    answer = "1"
  )
}

ui <- fluidPage(
  titlePanel("Debugging test"),
  fluidRow(
    column(12,
           numericInput("ProblemSelectionNo", 
                        "Select Problem no", 
                        value = 1, min = 1, max = maxProblem),
           radioButtons("answerInput", label = "Select answer",
                        choices = choices_answer[[1]][["choices"]]),
           verbatimTextOutput("ListData")
    )
  )
)

server <- function(input, output, session) {
  
  rv <- reactiveValues(lst = choices_answer)
  
  observeEvent(input$ProblemSelectionNo, {
    updateRadioButtons(session, "answerInput", 
                       choices = rv$lst[[input$ProblemSelectionNo]][["choices"]], 
                       selected = rv$lst[[input$ProblemSelectionNo]][["answer"]])
  })
  
  observeEvent(input$answerInput, {
    rv$lst[[input$ProblemSelectionNo]][["answer"]] <- input$answerInput
  })
  
  output$ListData <- renderPrint({rv$lst})
  
}

# Run the application 
shinyApp(ui = ui, server = server)