【问题标题】:Loading shiny module only when menu items is clicked仅在单击菜单项时加载闪亮模块
【发布时间】:2019-04-02 15:07:49
【问题描述】:

背景

在模块化1 Shiny 应用程序中,我只想在单击 上的菜单项时加载模块。如果未访问菜单项,我不想加载模块。

基本应用

app.R

# Libs
library(shiny)
library(shinydashboard)

# Source module
source("sample_module.R")

ui <- dashboardPage(
    dashboardHeader(title = "Dynamic sidebar"),
    dashboardSidebar(sidebarMenuOutput("menu")),
    dashboardBody(tabItems(
        tabItem(tabName = "tab_one", h1("Tab One")),
        tabItem(tabName = "tab_two", sampleModuleUI("sampleModule"))
    ))
)

server <- function(input, output) {

    callModule(sampleModuleServer, "sampleModule")

    output$menu <- renderMenu({
        sidebarMenu(
            menuItem(
                "Menu item 1",
                icon = icon("calendar"),
                tabName = "tab_one"
            ),
            menuItem(
                "Menu item 2",
                icon = icon("globe"),
                tabName = "tab_two"
            )
        )
    })
}

shinyApp(ui, server)

sample_module.R

sampleModuleServer <- function(input, output, session) {
    output$plot1 <- renderPlot({
        plot(mtcars)
    })
}

sampleModuleUI <- function(id) {
    ns <- NS(id)

    plotOutput(ns("plot1"))

}

期望的实现

仅当单击相关菜单项时,所需的实现才会加载sample_module。关于2的行:

不要从 observeEvent 内部调用 callModule;保持在顶层。获取返回的反应表达式,并使用 eventReactive 将其包装在按钮单击中。并使用输出中的 eventReactive 等。

x <- callModule(...)
y <- eventReactive(input$go, x())
output$tbl <- DT::renderDataTable(y())

尝试

app.R (已修改)

# Libs
library(shiny)
library(shinydashboard)

# Source module
source("sample_module.R")

ui <- dashboardPage(
    dashboardHeader(title = "Dynamic sidebar"),
    dashboardSidebar(sidebarMenuOutput("menu")),
    dashboardBody(tabItems(
        tabItem(tabName = "tab_one", h1("Tab One")),
        tabItem(tabName = "tab_two", sampleModuleUI("sampleModule"))
    ))
)

server <- function(input, output) {

    eventReactive(eventExpr = input$tab_two,
                  valueExpr = callModule(sampleModuleServer, "sampleModule")
    )

    output$menu <- renderMenu({
        sidebarMenu(
            menuItem(
                "Menu item 1",
                icon = icon("calendar"),
                tabName = "tab_one"
            ),
            menuItem(
                "Menu item 2",
                icon = icon("globe"),
                tabName = "tab_two"
            )
        )
    })
}

shinyApp(ui, server)

问题

应用程序运行但模块未加载。问题:

  • 如何在仪表板菜单项上正确调用eventReactivetab_item 似乎没有 id 参数是 tabName 在那种情况下等效?
  • 链接的讨论是指刷新一个表。我正在尝试找出适用于包含大量界面元素和精细服务器调用的模块的示例。

单击菜单项 2 应显示 sample_module.R 文件中的内容。


1Modularizing Shiny app code

2Google groups: activate module with actionButton


更新

我尝试使用以下语法显式强制模块进入应用程序环境加载:

eventReactive(eventExpr = input$tab_two,
              valueExpr = callModule(sampleModuleServer, "sampleModule"),
              domain = MainAppDomain
)

在哪里

MainAppDomain <- getDefaultReactiveDomain()

【问题讨论】:

    标签: shinydashboard r shiny shinydashboard shiny-reactivity


    【解决方案1】:

    编辑:删除 Joe Cheng 的顶级声明:

    # Libs
    library(shiny)
    library(shinydashboard)
    
    # Source module
    source("sample_module.R")
    
    ui <- dashboardPage(
      dashboardHeader(title = "Dynamic sidebar"),
      dashboardSidebar(sidebarMenuOutput("menu")),
      dashboardBody(tabItems(
        tabItem(tabName = "tab_one", h1("Tab One")),
        tabItem(tabName = "tab_two", sampleModuleUI("sampleModule"))
      ))
    )
    
    server <- function(input, output) {
    
      observeEvent(input$tabs,{
        if(input$tabs=="tab_two"){
          callModule(sampleModuleServer, "sampleModule")
        }
      }, ignoreNULL = TRUE, ignoreInit = TRUE)
    
      output$menu <- renderMenu({
        sidebarMenu(id = "tabs",
                    menuItem(
                      "Menu item 1",
                      icon = icon("calendar"),
                      tabName = "tab_one"
                    ),
                    menuItem(
                      "Menu item 2",
                      icon = icon("globe"),
                      tabName = "tab_two"
                    )
        )
      })
    }
    
    shinyApp(ui, server)
    

    此外,您的 sidebarMenu 需要一个 id 才能访问选定的选项卡;请查看闪亮仪表板documentation

    【讨论】:

    • 非常感谢您的关注。不确定这是否有效。为了测试,在sampleModuleServer 中我已经包含了stop("Module loaded, crashing...")。现在应用程序在启动时崩溃(它不会启动)。而在我看来,它不应该只有在我触发调用此模块的事件(单击链接)时才会崩溃。这是一个合理的假设吗?
    • 好吧,看来我们需要加入黑暗面并使用observeEvent。 - 请检查我的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 2019-09-02
    • 2017-04-12
    相关资源
    最近更新 更多