r - 监听动态创建的闪亮模块
问题描述
我想在我的主应用程序中动态创建模块。这些模块还应该包含一个delete
按钮,我想在该按钮上删除我的应用程序中的模块。
以下代码实现了这一点,但前提是我添加了对自身的依赖,这意味着每当我添加新模块handlers
时,观察者也会被触发。
从概念上讲,我想使用isolate(handlers())
,因为我不想依赖于handlers
自身,而只想依赖于handlers
.
那么为什么不起作用 isolate(handlers())
呢?如何正确依赖模块中的反应器?
library(shiny)
library(magrittr)
example_ui <- function(id) {
ns <- NS(id)
fluidRow(id = id,
h3(id),
actionButton(ns("delete"), "Delete Me!")
)
}
example_server <- function(input, output, session) {
killMe <- reactiveVal(FALSE)
observeEvent(input$delete, killMe(TRUE))
list(delete = killMe)
}
ui <- fluidPage(actionButton("add", "Add"), div(id = "container"))
server <- function(input, output, session) {
handlers <- reactiveVal(list())
n <- 1
observeEvent(input$add, {
id <- paste0("ex_", n)
n <<- n + 1
insertUI("#container", "beforeEnd", example_ui(id))
new_handler <- setNames(list(callModule(example_server, id)),
id)
handlers(c(handlers(), new_handler))
})
observe({
## would not work: isolate(handlers())
hdls <- handlers()
deregister <- lapply(names(hdls), function(id) {
handle <- hdls[[id]]
if (!is.null(handle) && handle$delete()) {
removeUI(paste0("#", id))
id
} else {
NULL
}
}) %>% purrr::flatten_chr()
hdls[deregister] <- NULL
handlers(hdls)
})
}
shinyApp(ui, server)
解决方案
所以我想这样做的正确方法是在这样observers
的变化上创建handlers
:
server <- function(input, output, session) {
handlers <- reactiveVal(list())
observers <- list()
n <- 1
observeEvent(input$add, {
id <- paste0("ex_", n)
n <<- n + 1
insertUI("#container", "beforeEnd", example_ui(id))
new_handler <- setNames(list(callModule(example_server, id)),
id)
handlers(c(handlers(), new_handler))
})
observe({
hds <- handlers()
req(length(hds) > 0)
new <- setdiff(names(hds),
names(observers))
obs <- setNames(lapply(new, function(n) {
observeEvent(hds[[n]]$delete(), {
removeUI(paste0("#", n))
hds <- handlers()
hds[n] <- NULL
handlers(hds)
observers[n] <<- NULL
}, ignoreInit = TRUE)
}), new)
observers <<- c(observers, obs)
})
}
推荐阅读
- patch - 如何正确避免意外补丁完成?
- javascript - 如何从实时站点而不是本地节点服务器获取数据库数据
- postgresql - 在 postgres 中每个表的每个实体的属性上搜索一个字符串
- node.js - 在 GAE 中的反向代理后面记录正确的用户 ip
- sqlite - Flask 应用程序在 Heroku 服务器上崩溃 - (at=error, code=H10)
- c# - 使用复杂对象的嵌套 asp 中继器
- android - 给定场景的测试方法的正确名称是什么?
- javascript - 如何将输入值存储到php变量
- cypress - 赛普拉斯:文件选择器对话框只能在用户激活时显示
- java - org.apache.derby.jdbc.ClientDriver;无法连接