使用 purrr::walk 来设置多个事件观察者
using purrr::walk to instate multiple event observers
我有一组变量用作 html 元素上的 id,具有匹配函数(方便命名为 varname.helper()),我想在触发事件时调用它们相应的 html 元素。
我尝试了以下方法:
server <- function(input, output, session) {
observables <- c("foo1", "foo2", "foo3") # they are obviously much more than 3 vars...
observables %>% walk(function(x) {
observeEvent(quo(!!sym(paste0("input$", x))), quo(!!sym(paste0(x, ".helper"))(input)), handler.quoted=TRUE)
}
但是没有用。有什么想法吗?
您的问题从这里开始。整洁的评估不是解决这个问题的最佳方法。
observeEvent(quo(!!sym(paste0("input$", x))),
quo(!!sym(paste0(x, ".helper"))(input)), handler.quoted=TRUE)
您想要(对吗?)获得 input$foo1
和 foo1.helper
。使用您的代码,最终结果是 quo
、sym
和感叹号的簇。
首先,如果所有的辅助变量都在做同样的事情,为什么要创建许多名为 foo1.helper
的独立变量?将它们放在一个列表中会更有意义,因此您可以使用任何一种 looping/mapping 让您的生活更轻松:
helpers <- list(foo1 = whatever..., foo2 = whatever...)
接下来,
quo(!!sym(paste0("input$", x)))
为您提供了一个具有特定用例的相当复杂的对象。与其使用 $
,不如使用双括号 selection:
input[[x]]
这使您可以 select 使用字符变量 x
根据名称从列表中选择一个项目。这些更容易使用。 $
语法只是糖,不会让您轻松使用字符值。
总结一下:
observeEvent(input[[x]], quote(helpers[[x]](input)), handler.quoted = TRUE)
这里有一个简短的例子,说明如何在您的代码中加入这些东西。请注意,您必须在此处使用 purrr::walk
,因为您不能使用 for
循环。 for
循环与 shiny 内部注册观察者等的特定方式不能很好地协同工作。
因此您的代码将变为:
library(shiny)
library(purrr)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("foo1", "Foo 1"),
actionButton("foo2", "Foo 2")
),
"Nothing here"
)
)
server <- function(input, output) {
helpers <- list(foo1 = quote(cat("foo 1; ")), foo2 = quote(cat("foo 2; ")))
purrr::walk(c("foo1", "foo2"), ~ observeEvent(input[[.x]],
helpers[[.x]], handler.quoted = TRUE))
}
shinyApp(ui = ui, server = server)
我有一组变量用作 html 元素上的 id,具有匹配函数(方便命名为 varname.helper()),我想在触发事件时调用它们相应的 html 元素。
我尝试了以下方法:
server <- function(input, output, session) {
observables <- c("foo1", "foo2", "foo3") # they are obviously much more than 3 vars...
observables %>% walk(function(x) {
observeEvent(quo(!!sym(paste0("input$", x))), quo(!!sym(paste0(x, ".helper"))(input)), handler.quoted=TRUE)
}
但是没有用。有什么想法吗?
您的问题从这里开始。整洁的评估不是解决这个问题的最佳方法。
observeEvent(quo(!!sym(paste0("input$", x))),
quo(!!sym(paste0(x, ".helper"))(input)), handler.quoted=TRUE)
您想要(对吗?)获得 input$foo1
和 foo1.helper
。使用您的代码,最终结果是 quo
、sym
和感叹号的簇。
首先,如果所有的辅助变量都在做同样的事情,为什么要创建许多名为 foo1.helper
的独立变量?将它们放在一个列表中会更有意义,因此您可以使用任何一种 looping/mapping 让您的生活更轻松:
helpers <- list(foo1 = whatever..., foo2 = whatever...)
接下来,
quo(!!sym(paste0("input$", x)))
为您提供了一个具有特定用例的相当复杂的对象。与其使用 $
,不如使用双括号 selection:
input[[x]]
这使您可以 select 使用字符变量 x
根据名称从列表中选择一个项目。这些更容易使用。 $
语法只是糖,不会让您轻松使用字符值。
总结一下:
observeEvent(input[[x]], quote(helpers[[x]](input)), handler.quoted = TRUE)
这里有一个简短的例子,说明如何在您的代码中加入这些东西。请注意,您必须在此处使用 purrr::walk
,因为您不能使用 for
循环。 for
循环与 shiny 内部注册观察者等的特定方式不能很好地协同工作。
因此您的代码将变为:
library(shiny)
library(purrr)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("foo1", "Foo 1"),
actionButton("foo2", "Foo 2")
),
"Nothing here"
)
)
server <- function(input, output) {
helpers <- list(foo1 = quote(cat("foo 1; ")), foo2 = quote(cat("foo 2; ")))
purrr::walk(c("foo1", "foo2"), ~ observeEvent(input[[.x]],
helpers[[.x]], handler.quoted = TRUE))
}
shinyApp(ui = ui, server = server)