2017-07-18 53 views
2

我正在开发一个应用程序,其中我使用模块来显示不同选项卡的UI内容。然而,它看起来像模块不与主要(或父母)应用程序进行通信。它显示正确的UI,但在单击actionButton时无法执行observeEvent函数,它应更新当前选项卡并显示第二个选项卡。observeEvent在模块中使用的闪亮功能不起作用

在我的代码中,我创建了一个名称空间函数,并将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) 

回答

3

的observeEvent的作品,但因为模块只能看到和知道给他们作为输入参数变量,它不知道指定的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) 

enter image description here

+0

谢谢你的帮助shosaco,我现在所发生的事情的一个更好的把握。然而,似乎这个解决方案只能工作一次。如果你点击按钮,然后回到第一个标签并重新点击它,没有任何反应 – MaxPlank

+0

是的,这只是一个简单的例子,我们只是将打开的选项卡更改为“两个”并且从不回到一个。相应地更新我的示例。技巧:为模块提供有关当前打开的选项卡('input $ tabsPanel')的信息,但是,必须将其封装为反应式,我将其称为“tabsPanel”。然后模块可以通过调用'tabsPanel()'来知道打开的标签。它在这里解释:https://www.rstudio.com/resources/webinars/understanding-shiny-modules/(大约42:15) – shosaco

+0

我不能在我的代码中实现输入$ tabsPanel,以便应用程序始终知道它是什么标签。在你的例子中,如果你点击一次按钮,然后回到第一个选项卡,而不是使用按钮,那么应用程序不知道你在一个新的选项卡上,并且按钮不起作用。我不知道如何确保应用程序在任何时候知道哪个选项卡是开放的 – MaxPlank