如何在shiny中创建动态数量的observeEvent?

Raj*_*aha 5 r shiny

在这里,我尝试复制我原来的问题。如果您单击“添加细分”,以下闪亮代码将创建“子细分”按钮。

现在,“添加子段”按钮应在每次单击时给出单行文本。但我注意到,它创建了(1 + 单击的按钮后“添加分段”按钮的数量)许多行。

对于单个observeEvent,它正在工作(代码被注释掉)。

library(shiny)

ui <- fluidPage(
  verbatimTextOutput("txt",placeholder = T), #"It is Created for Testing"
  actionButton("addSeg", "Add a Segment"),
  uiOutput("myUI")
)

server <- function(input, output, session) {
  alld <- reactiveValues()
  alld$ui <- list()

  # Action to add new Segment
  observeEvent(input$addSeg,{
    alld$ui[[length(alld$ui)+1]] <- list(actionButton(paste0("addSub_",(length(alld$ui)+1)), "Add a Sub Segment"))
  })

  # Action to add new Sub Segment
  # observeEvent(input[[paste0("addSub_",1)]],{
  #   alld$ui[[1]][[length(alld$ui[[1]])+1]] <- paste0("addSub_",1)
  # })

  observeEvent(input$addSeg,{
    lapply(1:length(alld$ui), function(i){
      observeEvent(input[[paste0("addSub_",i)]],{
        alld$ui[[i]][[length(alld$ui[[i]])+1]] <- HTML(paste0("<br>addSub_",i,"<br>"))
      })
    })
  })

  output$myUI <- renderUI({alld$ui})

  output$txt <- renderText(class(alld$ui))
}

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

请帮忙...

在此输入图像描述

A. *_*tam 6

非常有趣的问题,也是一个非常值得称赞的代表。我设法找到了解决方案。您可以用以下内容替换您的服务器对象:

server <- function(input, output, session) {
  alld <- reactiveValues()
  alld$ui <- list()

  # Action to add new Segment
  observeEvent(input$addSeg,{
    new_id <- length(alld$ui) + 1
    sub_name <- paste0("addSub_", new_id)

    alld$ui[[new_id]] <- list(
      actionButton(sub_name, "Add a Sub Segment")
    )

    observeEvent(input[[sub_name]], {
      new_text_id <- length(alld$ui[[new_id]]) + 1
      alld$ui[[new_id]][[new_text_id]] <- HTML(paste0("<br>addSub<br>"))
    })
  })

  output$myUI <- renderUI({alld$ui})

  output$txt <- renderText({
    capture.output(str(alld$ui))
  })
}
Run Code Online (Sandbox Code Playgroud)

我们来谈谈你的原始代码。你的第一个观察者工作得很好。然而,第二个因素会导致不良行为。它返回一个新观察者列表,每个观察者对应addSub应用程序中当前的每个按钮。这意味着在第一次单击时,它会创建 的观察者,而在第二次单击时,它会返回和 的addSub_1观察者。然而,第一个观察者仍然存在。这意味着当您单击 时,有两个观察者做出响应,并且文本会显示两次。addSub_1addSub_2addSub_1addSub_1

我的解决方案是将两个观察者合二为一。当您单击 时addSeg,会在 UI 列表中创建该按钮,并且还会创建处理该按钮的观察者。这样,就不会出现重复,并且应用程序将按预期工作。