You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Shiny应用中实现单步返回按钮(支持多步骤数据录入)

Shiny应用单步返回功能实现需求及示例代码

我开发了一个Shiny应用,逻辑是向用户展示单选按钮,用户选择后会给score/counter累加对应数值,同时弹出新的单选按钮,之前的单选按钮会被禁用。现在需要添加一个单步返回按钮,用于用户误操作时回退一步,具体要实现三点:

  • 隐藏最新出现的单选按钮
  • 重新激活上一个单选按钮
  • 调整score/counter的数值

目前已经用session$reload()实现了重置按钮,但会清空所有内容让用户重新开始,单步返回的体验会好很多。找过类似问题,但场景和我的需求不太匹配,以下是我的示例代码:

ui.R

ui <- fluidPage(
  
  shinyjs::useShinyjs(),
  # 用于显示总分的计数器
  verbatimTextOutput(outputId = "counter", placeholder = TRUE),
  
  # 初始单选按钮
  radioButtons(inputId = "a",
               label = "a",
               choices = c("10", "5"),
               selected = ""),
  
  # 动态生成的单选按钮UI容器
  uiOutput("b"),
  uiOutput("c"),
  uiOutput("d"),
  uiOutput("c1"),
  uiOutput("e"),
  uiOutput("f"),
  
  # 重置按钮
  actionButton(
    inputId = "reset_button",
    label = "Reset",
    width = "50%"
  ),
  textOutput("reset_val")
  
)

server.R

server <- function(input, output, session) {
  
  reset_rv <- reactiveVal(value = 0L)
  
  # 初始化计数器为0
  counter <- reactiveValues(value = 0)
  
  # 跟踪用户选择的选项
  selected_options <- reactiveValues(
    a = NULL,
    b = NULL,
    d = NULL,
    c = NULL,
    e = NULL,
    f = NULL
  )
  
  # 处理选项a的选择事件
  observeEvent(input$a, {
    if (!is.null(input$a)) {
      selected_options$a <- input$a
      if (input$a == "5") {
        counter$value <- counter$value + 0
        output$b <- renderUI({
          radioButtons(inputId = "b",
                       label = "b",
                       choices = c("a", "10"),
                       selected = "")
        })
        
      } else if (input$a == "10") {
        counter$value <- counter$value + 8
        output$c <- renderUI({
          radioButtons(inputId = "c",
                       label = "c",
                       choices = c("L", "R"),
                       selected = "")
        })
      }
    }
    shinyjs::disable("a")
  })
  
  # 处理选项b的选择事件
  observeEvent(input$b, { 
    if (!is.null(input$b)) {
      selected_options$b <- input$b
      if (input$b == "5") {
        counter$value <- counter$value + 0
        output$d <- renderUI({
          radioButtons(inputId = "d",
                       label = "d",
                       choices = c("5", "10"),
                       selected = "")
        })
      } else if (input$b == "10") {
        counter$value <- counter$value + 6
        output$c1 <- renderUI({
          radioButtons(inputId = "c1",
                       label = "c",
                       choices = c("L", "R"),
                       selected = "")})
      }
      shinyjs::disable("a")
      shinyjs::disable("b")
    }
  })
  
  # 处理选项c的选择事件
  observeEvent(input$c, {
    if (!is.null(input$c)) {
      selected_options$c <- input$c
      if (input$c == "R") {
        counter$value <- counter$value + 0
        output$e <- renderUI({
          radioButtons(inputId = "e",
                       label = "e",
                       choices = c("5", "10"),
                       selected = "")
        })
      } else if (input$c == "L") {
        counter$value <- counter$value + 4
        output$f <- renderUI({
          radioButtons(inputId = "f",
                       label = "L",
                       choices = c("5", "10"),
                       selected = "")})
      }
      shinyjs::disable("a")
      shinyjs::disable("c")
    }    
  })  
  
  # 更新计数器显示
  output$counter <- renderText({
    paste("Score:", counter$value)
  })
  
  # 重置按钮逻辑
  observeEvent(input$reset_button, {
    reset_rv(input$reset_button)
    session$reload()
  })
  
}

运行代码

shinyApp(ui = ui, server = server)

内容的提问来源于stack exchange,提问作者ava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 20:27:50