2017-07-18 71 views
0

我需要我的Shiny模塊來隱藏/顯示名稱空間外的div。我試圖將div id傳遞給模塊服務器函數,並使用shinyjs來顯示/隱藏它,但那不起作用。我沒有收到錯誤,只是沒有顯示/隱藏div。閃亮的模塊訪問輸出命名空間外

我知道Shiny模塊文檔說模塊不能訪問命名空間外的輸出。但是,文檔確實爲模塊提供了使用反應來訪問名稱空間外的輸入的方法。

有誰知道是否有一種方法讓Shiny模塊訪問命名空間之外的輸出?

這裏是我想要做的事:

### ui.R ### 
header <- dashboardHeader(
    title = a(href = 'http://google.com') 
) 

dashboardPage(
    skin = 'black', 
    header, 

    dashboardSidebar(
    sidebarMenu(id='tabs', 
      menuItem('Edit Existing Client', tabName = 'client-info') 
    )), 

    dashboardBody(
    useShinyjs(), 
    fluidRow(
     tabItems(
     tabItem(tabName = "client-info", 
       div(selectClientModuleUI("clientinfons")), 
       div(id='editclientinfo', uiOutput('editclientstuff')) 
     ) 
    ) 
    ) 
) 
) 

### server.R ### 
shinyServer(function(session,input, output) { 

    output$editclientstuff <- renderUI({ 
    div(
     fluidRow(
     column(6, 
      textInput('editname', "Display name", value ='Testing name') 
     ), 
     column(6, 
       numericInput('editastart','Start', value ='3') 
     ) 
    ) 
    ) 
    }) 


    callModule(selectClientModule, 'clientinfons', 'editclientinfo') 
    shinyjs::hide(id='editclientstuff') 
}) 

### in global.R ### 
selectClientModuleUI <- function(id){ 
    ns <- NS(id) 

    clientlist = c(0, 1, 2) 
    names(clientlist) = c('Choose client', 'Fred', 'Kim') 

    div( 
    selectInput(ns('selectclient'), 'Select client to edit', choices = clientlist, selected = NULL, multiple = FALSE) 
) 
} 

selectClientModule <- function(input, output, session, divtoshow = ''){ 
    observeEvent(input$selectclient, { 
    if (!is.null(input$selectclient) && input$selectclient > 0){ 
     print(paste0("showing ", divtoshow)) 
     shinyjs::show(divtoshow) 
    } 
    }) 

} 

回答

0

我放棄價值作爲反應是可能的(不作爲反應的值)的模塊。您可以更改模塊中的反應性值並將反應從模塊返回給應用程序(請注意,返回反應本身,而不是它的值)。以下應用從模塊內部切換主應用中的「divotoshow」。如果沒有選擇,它是隱藏的,否則它顯示(注意,我調整你的代碼有點,所以它是作爲一個獨立的應用程序):

library(shinydashboard) 
library(shinyjs) 


# Module 
selectClientModuleUI <- function(id){ 
    ns <- NS(id) 

    clientlist = c(0, 1, 2) 
    names(clientlist) = c('Choose client', 'Fred', 'Kim') 

    div( 
    selectInput(ns('selectclient'), 'Select client to edit', choices = clientlist, selected = NULL, multiple = FALSE) 
) 
} 

selectClientModule <- function(input, output, session, divtoshow){ 

    observeEvent(input$selectclient, { 
    if (input$selectclient > 0){ 
     print(paste0("showing editclientinfo")) 

     divtoshow("editclientinfo") # set the div to show to "editclientinfo", this will be visible outside the module 
    }else{ 
     divtoshow("") # set the div to show to "", if nothing was chosen 
    } 
    }) 

    # return the div to show as reactive to the main app 
    return(divtoshow) 
} 


# Main App 
ui <- shinyUI(
    dashboardPage(
    skin = 'black', 
    dashboardHeader(
     title = a(href = 'http://google.com') 
    ), 
    dashboardSidebar(
     sidebarMenu(id='tabs', 
        menuItem('Edit Existing Client', tabName = 'client-info') 
    )), 

    dashboardBody(
     useShinyjs(), 
     fluidRow(
     tabItems(
      tabItem(tabName = "client-info", 
        div(selectClientModuleUI("clientinfons")), 
        div(id='editclientinfo', uiOutput('editclientstuff')) 
     ) 
     ) 
    ) 
    ) 
)) 

server <- shinyServer(function(session,input, output) { 

    output$editclientstuff <- renderUI({ 
    div(
     fluidRow(
     column(6, 
       textInput('editname', "Display name", value ='Testing name') 
     ), 
     column(6, 
       numericInput('editastart','Start', value ='3') 
     ) 
    ) 
    ) 
    }) 

    # store the div to show in a reactive 
    divtoshow <- reactiveVal('') 

    # divtoshow can be changed in side this module, so it's a return value 
    divtoshow <- callModule(selectClientModule, 'clientinfons', divtoshow) 

    # observe the value of divtoshow and toggle the corresponding div 
    observeEvent(divtoshow(), { 
     if(divtoshow() == "editclientinfo"){ 
     shinyjs::show("editclientinfo") 
     }else{ 
     shinyjs::hide("editclientinfo") 
     } 

    }) 
}) 

shinyApp(ui, server) 
+0

很好的答案。我將一個大代碼分解成模塊。想知道是否有可能在sidebarpanel和dashboardbody中的下拉輸入和條件面板和outbput?我遇到的所有例子都有輸入和圖表/表格輸出。有什麼例子可以指導我嗎? – user5249203

+0

只需將所有必要的元素放入側邊欄即可。 – shosaco