当使用多个动态观察者时,如何识别Shiny中触发了哪个观察者

时间:2019-03-31 06:59:33

标签: r shiny lapply reactive

我在选项卡中生成了一组动态UI表单。我使用了动态的watchEvents来检查正在保存的表单。 请查看下面的代码

library(shiny)

ui <- fluidPage(
  actionButton("generate_tab","Generate Tabs"),
  tabsetPanel(id="tabs",
              uiOutput('tabsN')),
  dataTableOutput("saved_tabs_output")
)

server <- function(input, output, session) {
  rv<- reactiveValues(no_of_tabs =0)

  #generating the UI dynamically
 observeEvent(input$generate_tab,{
   rv$no_of_tabs <- rv$no_of_tabs + 1
   appendTab(inputId = "tabs", 
             tabPanel(title = paste0("Tab_",rv$no_of_tabs),
             selectInput(paste0("Input",rv$no_of_tabs),paste0("Input",rv$no_of_tabs), choices = c('',LETTERS), selected = NULL),
             actionButton(paste0("submit_input",rv$no_of_tabs),"submit input")
             )
   )})

# Reading the inputs upon clicking of Submit Input in each tab
   #dynamic Observe Event needs to be set up dependent on number of Tabs (rv$no_of_tabs)

   observeEvent(lapply(paste0("submit_input",1:rv$no_of_tabs), function(x){input[[x]]

   }
   ),{
     rv$inputs <-sapply(paste0("Input",1:rv$no_of_tabs), 
                        function(x)input[[x]])

        },ignoreInit = TRUE  )



   output$saved_tabs_output <- renderDataTable({
     as.data.frame(rv$inputs) 
   })


}

shinyApp(ui, server)

因为在一个名为eventEvent的Lapply公式中检查了多次提交按钮单击,所以它也接受来自未提交表单的输入。这是一个示例

第1步:点击“生成”选项卡4次以生成Tab1,Tab2,Tab3,Tab4。单击“ Tab 1” enter image description here

步骤2:在标签1中选择B。请勿按Submit(提交)。 enter image description here

第3步:在标签4中选择D,然后点击Submit enter image description here

所需的输出是仅更新Input4,而不更新Input1,但是在这种情况下,B和D均被保存。关于如何解决此问题的任何指示?

1 个答案:

答案 0 :(得分:0)

Geovany的评论有所帮助。 link也为我提供了帮助。 诀窍是只将一个观察者与每个Submit按钮相关联。

这是有效的代码,以防对任何人有用

library(shiny)
library(purrr)
options(shiny.reactlog = TRUE)
ui <- fluidPage(
  actionButton("generate_tab", "Generate Tabs"),
  tabsetPanel(id = "tabs",
              uiOutput('tabsN')),
  verbatimTextOutput("rvInput")

)

server <- function(input, output, session) {
  # browser()
  rv <- reactiveValues(no_of_tabs = 0L,
                       inputs = list()
                       )

  #generating the UI dynamically
  observeEvent(input$generate_tab, {
    rv$no_of_tabs <- rv$no_of_tabs + 1
    appendTab(inputId = "tabs",
              tabPanel(
                title = paste0("Tab_", rv$no_of_tabs),
                selectInput(
                  paste0("Input", rv$no_of_tabs),
                  paste0("Input", rv$no_of_tabs),
                  choices = c('', LETTERS),
                  selected = NULL
                ),
                actionButton(paste0("submit_input", rv$no_of_tabs), "submit input")
              ))
  })

  observe({
    lapply(1:rv$no_of_tabs, function(x) {
      observeEvent(input[[paste0("submit_input", x)]], {
        rv$inputs[[x]] <- input[[paste0("Input", x)]]
      })
    })
  })

  output$rvInput <- renderPrint({
    rv$inputs
  })

}

shinyApp(ui, server)