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

使用闪亮模块时,如何在shinydashboard中动态发布通知,r,shiny,shinydashboard,R,Shiny,Shinydashboard,当所有代码都在同一环境中时,可以很容易地在shinydashboard中创建通知。然而,当在闪亮的模块中包装代码时,我并不清楚如何仍然可以创建通知。在我的使用案例中,应用程序中的每个选项卡都有自己的模块,用于仪表板主体。我看不到一个明显的方式来让通知工作,这应该张贴在仪表板标题 我问这个问题是为了回答这个问题,因为我在试图解决这个问题时没有找到任何好的资源。关键是在不同的模块之间交换反应。在本例中,我专门为通知创建了一个模块。该模块返回允许其他模块发布通知的函数列表(使其成为有效的闭包)。注意使

当所有代码都在同一环境中时,可以很容易地在
shinydashboard
中创建通知。然而,当在闪亮的模块中包装代码时,我并不清楚如何仍然可以创建通知。在我的使用案例中,应用程序中的每个选项卡都有自己的模块,用于仪表板主体。我看不到一个明显的方式来让通知工作,这应该张贴在仪表板标题


我问这个问题是为了回答这个问题,因为我在试图解决这个问题时没有找到任何好的资源。

关键是在不同的模块之间交换反应。在本例中,我专门为通知创建了一个模块。该模块返回允许其他模块发布通知的函数列表(使其成为有效的闭包)。注意使用
parent.env
允许列表中的函数访问控制通知的内部响应值

服务器中
我们将通知功能列表输入到每个需要它的模块中。下面的应用程序演示了我的解决方案。好消息是通知模块可以在任何其他应用程序中重用

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)
库(闪亮)
图书馆(shinydashboard)
##模块
#与第一个选项卡相关的代码-------------------------------------------
tab1UI=功能(id){
ns=ns(id)
流动摄影(
h2(“这是表1”),
操作按钮(ns(“发送消息”),“发送消息”),
操作按钮(ns(“删除消息”),“删除最新消息”)
)
}
tab1Server=函数(输入、输出、会话、notifficationModule){
ObserveeEvent(输入$send_消息{
NotificationModule$push_通知(notificationItem(sprintf('Tab 1:在%s'推送通知,Sys.time()))
}) 
observeEvent(输入$remove_消息{
notifficationModule$pop_notification()
})
}
#与第二个选项卡相关的代码------------------------------------------
tab2UI=函数(id){
ns=ns(id)
流动摄影(
h2(“这是表2”),
操作按钮(ns(“发送消息”),“发送消息”),
操作按钮(ns(“删除消息”),“删除最新消息”)
)
}
tab2Server=函数(输入、输出、会话、notifficationModule){
ObserveeEvent(输入$send_消息{
NotificationModule$push_通知(notificationItem(sprintf('Tab2:在%s'推送通知,Sys.time()))
}) 
observeEvent(输入$remove_消息{
notifficationModule$pop_notification()
})
}
#通知模块-------------------------------------------------
notificationUI=函数(id){
ns=ns(id)
下拉菜单输出(ns(“通知”)
}
notificationServer=函数(输入、输出、会话){
通知列表=反应值()
输出$notifications=renderMenu({
验证(需要(通知列表(),消息=FALSE))
下拉菜单(类型='notifications',徽章状态='warning',.list=notification_list())
})
返回(列表)(
推送通知=功能(消息){
pf=parent.env(环境())
pf$通知列表(c(pf$通知列表(),列表(消息)))
},
pop_通知=函数(){
pf=parent.env(环境())
pf$notification_list(notification_list()[-length(pf$notification_list())]))
}
))
}
#主应用程序----------------------------------------------------------------
用户界面