Shiny模块化事件总线:解耦复杂UI的通信
利用shiny模块与自定义事件总线,实现跨模块状态共享,避免父子模块直接调用带来的耦合。 · 难度:入门 · +10XP
Shiny模块化事件总线:解耦复杂UI的通信
当Shiny应用超过20个模块时,直接通过callModule传递reactive会变得难以维护。本教程实现一个基于shiny::makeReactiveBinding()的事件总线(event bus):模块A发布事件(如'data_updated'),模块B订阅该事件并响应,两个模块完全独立。核心是创建一个总线对象,包含list、trigger、subscribe方法。最后构建一个包含数据上传、过滤、绘图三个模块的仪表盘,过滤器变化仅通知绘图模块,无需变动上传模块。
# 迷你事件总线
create_bus <- function() {
listeners <- list()
list(
subscribe = function(event, callback) {
listeners[[event]] <- c(listeners[[event]], callback)
},
trigger = function(event, value) {
for(f in listeners[[event]]) f(value)
}
)
}
bus <- create_bus()
bus$subscribe('update', function(x) print(x))
bus$trigger('update', 'hello') # 打印 'hello'