简体   繁体   English

使用闪亮模块时,如何在闪亮仪表板中动态发布通知

[英]How can I dynamically post notifications in shinydashboard when using shiny modules

When all code is in the same evironment, it is easy to create notifications in shinydashboard . 当所有代码都在同一环境中时,很容易在shinydashboard创建通知。 However, when wrapping code in shiny modules it is not obvious to me how I can still create notifications. 但是,将代码包装在闪亮的模块中时,对我来说仍然不知道如何创建通知。 In my use case each tab in the app has it's own module which is used in the dashboard body. 在我的用例中,应用程序中的每个选项卡都有其自己的模块,该模块在仪表板主体中使用。 I don't see an obvious way to get notifications working, which should be posted in the dashboard header. 我没有看到一种明显的方法来使通知正常工作,应该将其发布在仪表板标题中。

I asked this question specificaly to answer it because I did not find any good resources when trying to solve this issue. 我专门问这个问题是为了回答它,因为在尝试解决此问题时我找不到任何好的资源。

The crux is to exchange reactives between the different modules. 关键是要在不同模块之间交换反应性。 In this example I created a module specifically for the notifications. 在此示例中,我创建了一个专门用于通知的模块。 The module returns a list of functions (making it a closure effectivally) that allow other modules to post notifications. 该模块返回允许其他模块发布通知的功能列表(有效地使其闭合)。 Note the use of parent.env to allow the function in the list to access the internal reactive value that controls the notifications. 请注意使用parent.env允许列表中的函数访问控制通知的内部响应值。

In the server we input the notification function list into each of the modules that needs it. server我们将通知功能列表输入到需要它的每个模块中。 The following app illustrates my solution. 以下应用说明了我的解决方案。 The nice thing is that the notification module can be reused in any other app. 令人高兴的是,通知模块可以在任何其他应用程序中重用。

library(shiny)
library(shinydashboard)

## Modules
# Code related to the first tab -------------------------------------------
tab1UI = function(id) {
  ns = NS(id)

  fluidPage(
    h2('This is tab 1'),
    actionButton(ns('send_message'), 'Send a message'),
    actionButton(ns('remove_message'), 'Remove most recent message')
  )
}
tab1Server = function(input, output, session, notifficationModule) {
  observeEvent(input$send_message, {
    notifficationModule$push_notification(notificationItem(sprintf('Tab 1: Pushed a notification at %s', Sys.time())))
  }) 
  observeEvent(input$remove_message, {
    notifficationModule$pop_notification()
  })
}


# Code related to the second tab ------------------------------------------
tab2UI = function(id) {
  ns = NS(id)

  fluidPage(
    h2('This is tab 2'),
    actionButton(ns('send_message'), 'Send a message'),
    actionButton(ns('remove_message'), 'Remove most recent message')
  )
}
tab2Server = function(input, output, session, notifficationModule) {
  observeEvent(input$send_message, {
    notifficationModule$push_notification(notificationItem(sprintf('Tab2: Pushed a notification at %s', Sys.time())))
  }) 
  observeEvent(input$remove_message, {
    notifficationModule$pop_notification()
  })
}


# The notification module -------------------------------------------------
notificationUI = function(id) {

  ns = NS(id)

  dropdownMenuOutput(ns('notifications'))
}
notificationServer = function(input, output, session) {
  notification_list = reactiveVal()
  output$notifications = renderMenu({
    validate(need(notification_list(), message = FALSE))
    dropdownMenu(type = 'notifications', badgeStatus = 'warning', .list = notification_list())
  })

  return(list(
    push_notification = function(message) {
      pf = parent.env(environment())
      pf$notification_list(c(pf$notification_list(), list(message)))
    },
    pop_notification = function() {
      pf = parent.env(environment())
      pf$notification_list(notification_list()[-length(pf$notification_list())])
    }
  ))
}


# Main app ----------------------------------------------------------------
ui <- dashboardPage(
  dashboardHeader(title = 'Notification Example', notificationUI('notificationUI')),
  dashboardSidebar(sidebarMenu(
    menuItem('Tab1', tabName = 'tab1'),
    menuItem('Tab2', tabName = 'tab2')
  )),
  dashboardBody(tabItems(
    tabItem(tabName = 'tab1', tab1UI('tab1UI')),
    tabItem(tabName = 'tab2', tab2UI('tab2UI'))
  ))
)

server <- function(input, output) { 
  notificationModule = callModule(notificationServer, 'notificationUI')
  callModule(tab1Server, 'tab1UI', notificationModule)
  callModule(tab2Server, 'tab2UI', notificationModule)
}

shinyApp(ui, server)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 `renderMenu` 在 shiny (shinydashboard) 中使用操作按钮动态添加额外的 `sidebarMenu`? - How do I dynamically add additional `sidebarMenu`s with an action button in shiny (shinydashboard) using `renderMenu`? 使用闪亮的模块和闪亮的仪表板:shiny.tag 错误 - Using shiny modules and shinydashboard: shiny.tag error 使用Shiny和Shinydashboard时如何使图标大小一致? - How to make the size of icon consistent when using Shiny and Shinydashboard? 使用Shinydashboard在闪亮的应用程序中未显示输出 - Output not displayed i shiny app using shinydashboard R Shiny:如何使用Shinydashboard库在Shiny应用程序中显示数据框 - R Shiny: how to display dataframe in shiny app using shinydashboard library 使用 Shiny 时自动更新 DT 有效,但在具有多个选项卡的闪亮仪表板中无效 - Automatically Updating a DT works when using Shiny, but not in shinydashboard with multiple tabs 我需要知道如何在RStudio中使饼形图变亮/变亮 - I need to know how to make pie chart in RStudio shiny/ shinydashboard 如何生成 Shinydashboard 的dashboardBody 的 PDF? - How can I generate a PDF of the dashboardBody of a shinydashboard? 在 R Shiny 中,当使用 renderUI/uiOutput 动态生成控件集时,如何通过引发事件来获取这些值或填充输入? - In R Shiny, when using renderUI/uiOutput to dynamically generate sets of controls, how can I harvest those values or populate input by causing events? 动态更新shinydashboard tabItems时如何保留内容 - How to keep content when dynamically updating shinydashboard tabItems
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM