2017-07-18 64 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