[英]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.