R Shiny在应用程序中打开和关闭具有UI和Server组件的模块

时间:2019-02-27 20:46:08

标签: r module shiny

我想知道是否有可能让我的用户在我的应用程序中打开和关闭某些模块。

我的模块在功能上每个都包含一个分析,并且从技术上讲具有服务器和UI功能。

我希望用户选择他/她想查看的巫婆模块/分析。

我已经尝试过(用于测试)将它们放在一个if else语句中,该语句侦听pickerinput。

此类应用程序的大多数精简示例:

  ui <- dashboardPage(
      dashboardHeader(title = NULL),
      dashboardSidebar(
          width = '100%',
          disable  = TRUE
      ),
      dashboardBody(
          fluidRow(
              box(
                  title = "Modular modules", width = NULL, background = "blue",
                  h5(
                      paste('Version: ', packageVersion("modular modules"))
                  )
              )
          )
          fluidRow(
              pickerInput(inputId = 'select_modules',
                          label = 'Moules',
                          choices = c('Mod1', 'Mod2'),
                          selected = NULL,
                          multiple = FALSE)
          ),
          uiOutput('modulesUI'))
          )

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

                observeEvent(input$select_modules,{
                    output$modulesUI <- renderUI(
                        if(input$select_modules == 'mod1'){
                        fluidRow(
                            mod1_UI(id = 'mod1')
                        )
                    } else if(input$select_modules == 'mod2'){
                        fluidRow(
                            mod2_UI(id = "mod2")
                        )
                    }
                    )
                })

            observeEvent(input$select_modules,{
                if(input$select_modules == 'mod1'){
                    callModule(mod1,
                               id = 'mod1',
                               ...
                                   )
                } else if(input$select_modules == 'mod2'){
                    callModule(mod2,
                               id = "mod2",
                              ...
                    )
                }
            })

我的解决方案不起作用。能做到吗?如果可以,怎么办?

1 个答案:

答案 0 :(得分:0)

我不知道您所说的“关闭”模块是什么意思,但是类似这样的事情却很有趣:

代码

## Define 2 modules
module1_ui <- function(id) {
  ns <- NS(id)
  tagList(
    h3("Distribution"),
    sliderInput(ns("sld"), "n", 10, 100, 10),
    plotOutput(ns("pl"))
  )}

module1 <- function(input, output, session) {
  output$pl <- renderPlot(hist(rnorm(input$sld)))
}

module2_ui <- function(id) {
  ns <- NS(id)
  tagList(
    h3("Boxplot"),
    numericInput(ns("nui"), "n:"),
    plotOutput(ns("pl"))
  )}

module2 <- function(input, output, session) {
  output$pl <- renderPlot(boxplot(rnorm(input$nui)))
}


## in the main ui have a select input and a ui placeholder 
## to select which module to show and to render it
ui <- fluidPage(
  selectInput("mod", "Module:", c("Module 1", "Module 2")),
  uiOutput("mod_placeholder")
)

## in the server call the handlers either statically or dynamically
server <- function(input, output, session) {
  active_handler <- reactiveVal()

  observe({
    req(input$mod)
    if (input$mod == "Module 1") {
      active_handler(callModule(module1, "m1"))
    } else {
      active_handler(callModule(module2, "m2"))
    }
  })


  ## a static approach like this would also work
  ## handler <- list(mod1 = callModule(module1, "m1"),
  ##                 mod2 = callModule(module2, "m2")) 

  output$mod_placholder <- renderUI({
    if (input$mod == "Module 1") {
      module1_ui("m1")
    } else {
      module2_ui("m2")
    }
  })
}

shinyApp(ui, server)

备注

这个玩具示例是非常难编码的,因此在您的用例中,我会将所有模块(ui和服务器)放在一个列表中,然后遍历该列表。然后添加一个新模块非常容易,因为您只需要将服务器和ui函数添加到此列表中,其余的将自动更新。