2017-07-18 4 views
2
funktioniert

Ich entwickle eine app, in dem ich Module verwenden unterschiedliche Registerkarte ui Inhalte angezeigt werden soll. Es scheint jedoch, dass das Modul nicht mit der Hauptanwendung (oder der übergeordneten App) kommuniziert. Es zeigt das richtige ui aber ist nicht in der Lage, die observeEvent Funktion auszuführen, wenn ein actionButton geklickt wird, sollte es die aktuelle Registerkarte aktualisieren und die zweite anzeigen.observeEvent Shiny Funktion in einem Modul verwendet nicht

In meinem Code habe ich eine Namespace-Funktion erstellt und die ID actionButton in ns() verpackt, aber es funktioniert immer noch nicht. Weiß jemand, was los ist?

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) 

Antwort

3

Die observeEvent funktioniert, aber da Module nur die Variablen, um sie als Eingangsparameter gegeben sehen und wissen, es kennt nicht die tabsetPanel angegeben und somit nicht aktualisieren kann. Dieses Problem kann mit einem reaktiven Wert gelöst werden, der als Parameter übergeben wird und innerhalb des Moduls geändert wird. Sobald es sich verändert hat, ist es weiß, in die Hauptanwendung und die tabsetPanel aktualisieren können:

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

Danke für Ihre Hilfe shosaco, ich habe jetzt ein besseres Verständnis von dem, was passiert ist. Es scheint jedoch, dass diese Lösung nur einmal funktioniert. Wenn Sie auf die Schaltfläche klicken, gehen Sie zurück in die erste Registerkarte und klicken Sie erneut darauf, nichts passiert – MaxPlank

+0

ja, es war nur ein minimales Beispiel, wir haben nur die offene Registerkarte auf "zwei" und nie wieder auf eins. Mein Beispiel wurde entsprechend aktualisiert. Trick: Geben Sie dem Modul die Informationen über die aktuell geöffnete Registerkarte ('input $ tabsPanel'), diese muss jedoch als reaktiv umschlossen werden, ich nannte es' tabsPanel'. Das Modul kann dann immer den geöffneten Tab durch Aufruf von 'tabsPanel()' kennen. Es wird hier erklärt: https://www.rstudio.com/resources/webinars/understanding-shiny-modules/ (um 42:15) – shosaco

+0

Ich kann nicht Eingang $ tabsPanel in meinem Code implementieren, so dass die App immer weiß, auf Welcher Tab ist es? Wenn Sie in Ihrem Beispiel einmal auf die Schaltfläche klicken und dann nicht mit der Schaltfläche zur ersten Registerkarte zurückkehren, weiß die App nicht, dass Sie sich auf einer neuen Registerkarte befinden und die Schaltfläche nicht funktioniert. Ich weiß nicht, wie man sicherstellen, dass die App jederzeit weiß, welche Registerkarte geöffnet sind – MaxPlank

Verwandte Themen