我正在尝试将reactives
添加到列表中并收听它们。我不明白为什么在下面的代码中dbg1
不能在dgb2
中看到任何输出。
唯一的区别是l2
在启动时将包含一个reactive
,而l1
仅在按下第一个按钮之后才包含,但在其他方面是相同的。
对此有任何解释吗?
library(shiny)
library(purrr)
ui <- fluidPage(
actionButton("add1", "Add to List 1"),
actionButton("add2", "Add to List 2"),
actionButton("rnd", "Generate Random"),
verbatimTextOutput("dbg1"),
verbatimTextOutput("dbg2"))
server <- function(input, output, session) {
l1 <- l2 <- list()
observeEvent(input$add1, {
l1 <<- c(l1, reactive({
input$rnd
sample(100, 1)
}))
})
observeEvent(input$add2, {
l2 <<- c(l2, reactive({
input$rnd
sample(100, 1)
}))
}, ignoreNULL = FALSE)
output$dbg1 <- renderPrint(map(l1, ~ .x()))
output$dbg2 <- renderPrint(map(l2, ~ .x()))
}
shinyApp(ui, server)
读完@stefan的答案和@starja的评论后,我想更精确地呈现这个问题。
我想要一个reactives
的动态容器。也就是说,动态创建的reactives
数量取决于某些输入来发挥作用。
我认为在我的代码中,renderPrint
的{{1}}仅在启动时被调用。它意识到没有dbg1
上下文(实际上仅在以后添加),因此永远不会回想它。在reactive
的情况下,它看到至少一个反应,因此又回来了。因此,我想我必须使dbg1
本身具有反应性(如@stefan指出的那样)
答案 0 :(得分:2)
不确定最终要达到的目标。但是在this post之后,您可以像这样使用reactiveVal
更新列表并打印出来:
library(shiny)
library(purrr)
ui <- fluidPage(
actionButton("add1", "Add to List 1"),
actionButton("add2", "Add to List 2"),
actionButton("rnd", "Generate Random"),
verbatimTextOutput("dbg1"),
verbatimTextOutput("dbg2"))
server <- function(input, output, session) {
l1 <- reactiveVal(value = list())
l2 <- reactiveVal(value = list())
rnd <- eventReactive(input$rnd, {
sample(100, 1)
})
observeEvent(input$add1, {
old_value <- l1()
l1(c(old_value, rnd()))
})
observeEvent(input$add2, {
old_value <- l2()
l2(c(old_value, rnd()))
})
output$dbg1 <- renderPrint(l1())
output$dbg2 <- renderPrint(l2())
}
shinyApp(ui, server)
答案 1 :(得分:0)
我猜是问题在于,dbg1
首先检查l1
时,它看不到任何反应性上下文(这是事实)。但是,它并没有意识到l1
最终包含一些reactives
,并且从不“调用”它。
因此,我认为我们必须使l1
更具反应性(由@Stefan启发):
server <- function(input, output, session) {
l1 <- l2 <- list()
r1 <- reactiveVal(list())
r2 <- reactiveVal(list())
observeEvent(input$add1, {
r1(c(r1(), reactive({
input$rnd
sample(100, 1)
})))
})
observeEvent(input$add2, {
r2(c(r2(), reactive({
input$rnd
sample(100, 1)
})))
}, ignoreNULL = FALSE)
output$dbg1 <- renderPrint(map(r1(), ~ .x()))
output$dbg2 <- renderPrint(map(r2(), ~ .x()))
}