收听列表中的反应
Listen to reactives in list
我正在尝试将 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
,它们根据某些输入执行它们的操作。
问题
我认为在我的代码中 dbg1
的 renderPrint
仅在启动时调用。它意识到没有 reactive
上下文(确实只是后来添加的)因此永远不会回忆起它。在 dbg1
的情况下,它至少看到一个反应并因此返回。所以我想我必须使 l1
本身具有反应性(正如@stefan 所指出的)
不确定您最终要达到什么目的。但是在 之后,您可以更新您的列表并通过使用 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)
我猜问题是当 dbg1
第一次检查 l1
时,它没有看到任何反应上下文(这是真的)。但是,它确实没有意识到 l1
最终包含一些 reactives
并且从不“召回”它。
因此,我认为我们必须通过使其本身具有反应性(受@Stefan 启发)来更明确地说明 l1
:
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()))
}
我正在尝试将 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
,它们根据某些输入执行它们的操作。
问题
我认为在我的代码中 dbg1
的 renderPrint
仅在启动时调用。它意识到没有 reactive
上下文(确实只是后来添加的)因此永远不会回忆起它。在 dbg1
的情况下,它至少看到一个反应并因此返回。所以我想我必须使 l1
本身具有反应性(正如@stefan 所指出的)
不确定您最终要达到什么目的。但是在 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)
我猜问题是当 dbg1
第一次检查 l1
时,它没有看到任何反应上下文(这是真的)。但是,它确实没有意识到 l1
最终包含一些 reactives
并且从不“召回”它。
因此,我认为我们必须通过使其本身具有反应性(受@Stefan 启发)来更明确地说明 l1
:
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()))
}