如何在初始化期间仅在子 tabPanel 上触发一次 observerEvent

How to trigger observerEvent on child tabPanel only once during initialization

在下面的应用程序中有很多选项卡,有些是父选项卡,有些是子选项卡。 我想在有人第一次点击子 tabPanel 时触发 observerEvent。现在,当有人点击任何子选项卡时,所有 observerEvent 函数都会被触发,这是错误的。谁能告诉我在单击子选项卡时只触发一次 observerEvent 的正确方法?

library(shiny)
library(shinydashboard)

sidebar <- dashboardSidebar(
  collapsed = FALSE,
  sidebarMenu(id = "menu_sidebar",
              conditionalPanel(
                condition = "input.main_tab == 'mother_tab' && (input.group_tab == 't_child1' || input.group_tab == 't_child2' || input.group_tab == 't_child3')",
                selectizeInput(inputId = "tc", label = "Select by:", choices = c("APPLE", "ORANGE", "PEAR"), selected = "APPLE")
              ),
              conditionalPanel(
                condition = "input.main_tab == 'tab_1'",
                selectizeInput(inputId = "t1", label = "Select by:", choices = c(as.character(30:40)))
              ),
              conditionalPanel(
                condition = "input.main_tab == 'tab_2'",
                selectizeInput(inputId = "t2", label = "Select by:", choices = c(as.character(40:50)))
              )
  )
)


body <- dashboardBody(
  fluidRow(
    tabsetPanel(id = "main_tab",
                selected = "mother_tab",
                tabPanel(title = "tab_1", "Tab content 1"),
                tabPanel(title = "tab_2", "Tab content 2"),
                tabPanel(title = "mother_tab",
                         tabsetPanel(type = "tabs", id = "group_tab", selected = "t_child2",
                                     tabPanel(title = "child_1", value = "t_child1", "Tab child content 1"),
                                     tabPanel(title = "child_2", value = "t_child2", "Tab child content 2"),
                                     tabPanel(title = "child_3", value = "t_child3", "Tab child content 3")
                         )
                )
                
    )
  )
)


shinyApp(
  ui = dashboardPage(
    dashboardHeader(title = "tabBoxes"),
    sidebar,
    body
  ),
  server = function(input, output, session) {
    observeEvent(eventExpr = input$main_tab, handlerExpr = {
      if(input$main_tab == 'tab_1')
        print("Tab content 1")
      else if(input$main_tab == 'tab_2')
        print("Tab content 2")
    })
    
    observeEvent(eventExpr = {input$group_tab == 't_child1'}, handlerExpr = {
        print("Child content 1")
      }, once = TRUE, ignoreInit = TRUE)
    
    observeEvent(eventExpr = {input$group_tab == 't_child2'}, handlerExpr = {
      print("Child content 2")
    }, once = TRUE, ignoreInit = TRUE)
    
    observeEvent(eventExpr = {input$group_tab == 't_child3'}, handlerExpr = {
      print("Child content 3")
    }, once = TRUE, ignoreInit = TRUE)
  }
)

observeEvent 监听输入 $group_tab 值的变化,不为 TRUE 或 FALSE.Instead 我们可以在观察者内部使用 switch 函数(或多个 if 语句)像这样:

library(shiny)
library(shinydashboard)

sidebar <- dashboardSidebar(
  collapsed = FALSE,
  sidebarMenu(
    id = "menu_sidebar",
    conditionalPanel(
      condition = "input.main_tab == 'mother_tab' && (input.group_tab == 't_child1' || input.group_tab == 't_child2' || input.group_tab == 't_child3')",
      selectizeInput(inputId = "tc", label = "Select by:", choices = c("APPLE", "ORANGE", "PEAR"), selected = "APPLE")
    ),
    conditionalPanel(
      condition = "input.main_tab == 'tab_1'",
      selectizeInput(inputId = "t1", label = "Select by:", choices = c(as.character(30:40)))
    ),
    conditionalPanel(
      condition = "input.main_tab == 'tab_2'",
      selectizeInput(inputId = "t2", label = "Select by:", choices = c(as.character(40:50)))
    )
  )
)


body <- dashboardBody(
  fluidRow(
    tabsetPanel(
      id = "main_tab",
      selected = "",
      tabPanel(title = "tab_1", "Tab content 1"),
      tabPanel(title = "tab_2", "Tab content 2"),
      tabPanel(
        title = "mother_tab",
        tabsetPanel(
          type = "tabs", id = "group_tab", selected = "",
          tabPanel(title = "child_1", value = "t_child1", "Tab child content 1"),
          tabPanel(title = "child_2", value = "t_child2", "Tab child content 2"),
          tabPanel(title = "child_3", value = "t_child3", "Tab child content 3")
        )
      )
    )
  )
)


shinyApp(
  ui = dashboardPage(
    dashboardHeader(title = "tabBoxes"),
    sidebar,
    body
  ),
  server = function(input, output, session) {
    nms_not_used <- reactiveVal(c("t_child1", "t_child2", "t_child3"))

    observeEvent(eventExpr = input$main_tab, handlerExpr = {
      if (input$main_tab == "tab_1") {
        print("Tab content 1")
      } else if (input$main_tab == "tab_2") {
        print("Tab content 2")
      }
    })

    observeEvent(input$group_tab, handlerExpr = {

      # create a vector with all the tabs names

      index <- which(nms_not_used() == input$group_tab)

      if (length(index) > 0) {
        # store the value
        cur_value <- nms_not_used()[[index]]
        # remove it from the names that are not used
        nms_not_used(nms_not_used()[-index])

        switch(cur_value,
          "t_child1" = print("Child content 1"),
          "t_child2" = print("Child content 2"),
          "t_child3" = print("Child content 3")
        )
      }
    }, , ignoreInit = TRUE)
  }
)