模块中使用的observeEvent功能不起作用

模块中使用的observeEvent功能不起作用,r,module,shiny,shiny-server,R,Module,Shiny,Shiny Server,我正在开发一个应用程序,其中我使用模块来显示不同选项卡的ui内容。但是,模块似乎不与主(或父)应用程序通信。它显示正确的ui,但无法执行observeEvent功能单击action按钮时,它应更新当前选项卡并显示第二个选项卡 在我的代码中,我创建了一个名称空间函数,并将actionButton的id包装在ns()中,但是它仍然不起作用。有人知道怎么了吗 library(shiny) moduleUI <- function(id){ ns <- NS(id) si

我正在开发一个应用程序,其中我使用模块来显示不同选项卡的ui内容。但是,模块似乎不与主(或父)应用程序通信。它显示正确的ui,但无法执行
observeEvent
功能单击
action按钮时,它应更新当前选项卡并显示第二个选项卡

在我的代码中,我创建了一个名称空间函数,并将
actionButton
的id包装在
ns()
中,但是它仍然不起作用。有人知道怎么了吗

library(shiny)

moduleUI <- function(id){

  ns <- NS(id)
      sidebarPanel(

        actionButton(ns("action1"), label = "click")
      )
}

module <- function(input, output, session){


  observeEvent(input$action1, {
    updateTabItems(session, "tabsPanel", "two")
  })
}

ui <- fluidPage(

            navlistPanel(id = "tabsPanel",

                         tabPanel("one",moduleUI("first")),
                         tabPanel("two",moduleUI("second"))
))
server <- function(input, output, session){
  callModule(module,"first")
  callModule(module,"second")

}

shinyApp(ui = ui, server = server)
库(闪亮)

moduleUIobserveEvent可以工作,但由于模块只看到并知道作为输入参数提供给它们的变量,因此它不知道指定的tabsetPanel,因此无法更新它。这个问题可以通过使用无功值来解决,无功值作为参数传递,并在模块内部进行更改。一旦更改,主应用程序就会知道它,并可以更新tabsetPanel:

library(shiny)
library(shinydashboard)

moduleUI <- function(id){

  ns <- NS(id)
  sidebarPanel(
    actionButton(ns("action1"), label = "click")
  )
}

module <- function(input, output, session, tabsPanel, openTab){

  observeEvent(input$action1, {
    if(tabsPanel() == "one"){  # input$tabsPanel == "one"
      openTab("two")
    }else{                     # input$tabsPanel == "two"
      openTab("one")
    }
  })

  return(openTab)
}

ui <- fluidPage(
  h2("Currently open Tab:"),
  verbatimTextOutput("opentab"),
  navlistPanel(id = "tabsPanel",
               tabPanel("one", moduleUI("first")),
               tabPanel("two", moduleUI("second"))
  ))


server <- function(input, output, session){
  openTab <- reactiveVal()
  observe({ openTab(input$tabsPanel) }) # always write the currently open tab into openTab()

  # print the currently open tab
  output$opentab <- renderPrint({
    openTab()
  })

  openTab <- callModule(module,"first", reactive({ input$tabsPanel }), openTab)
  openTab <- callModule(module,"second", reactive({ input$tabsPanel }), openTab)

  observeEvent(openTab(), {
    updateTabItems(session, "tabsPanel", openTab())
  })
}

shinyApp(ui = ui, server = server)
库(闪亮)
图书馆(shinydashboard)

谢谢你的帮助shosaco,我现在对发生的事情有了更好的了解。然而,这个解决方案似乎只起作用一次。如果您单击按钮,然后返回第一个选项卡并重新单击,没有发生任何情况是的,这只是一个最小的示例,我们只将打开的选项卡更改为“两个”,而从不返回一个。相应地更新了我的示例。技巧:向模块提供有关当前打开选项卡的信息(
input$tabsPanel
),但是,必须将其包装为反应式,我称之为
tabsPanel
。然后,模块可以通过调用
tabsPanel()
始终知道打开的选项卡。这里解释如下:(大约42:15)我无法在代码中实现input$tabsPanel,这样应用程序总是知道它在哪个选项卡上。在您的示例中,如果单击一次按钮,然后返回到第一个选项卡,而不是使用该按钮,则应用程序不知道您位于新选项卡上,并且该按钮不起作用。我不知道如何确保应用程序在任何时候都知道哪个选项卡是开放的。我对答案中的代码做了一点改进,以将其纳入其中(添加了一行
observe({openTab(input$tabsPanel)})
)。@shosaco,你为什么要做“openTab”