Dengarkan reactives dalam daftar

Oct 17 2020

Saya mencoba menambah reactivesdaftar dan mendengarkan mereka. Saya tidak mengerti mengapa dalam kode di bawah ini saya tidak melihat output apa pun dbg1saat berfungsi dgb2.

Satu-satunya perbedaan adalah itu l2akan berisi reactivesaat startup, sementara l1hanya setelah tombol pertama ditekan tetapi sebaliknya identik.

Ada penjelasan untuk ini?

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)

Setelah membaca jawaban dari @stefan dan komentar dari @starja, saya ingin membahas masalah ini lebih tepat.

Tujuan

Saya ingin wadah dinamis reactives. Artinya, jumlah yang dibuat secara dinamis reactives, yang melakukan tugasnya tergantung pada beberapa masukan.

Masalah

Saya rasa dalam kode saya, renderPrintfor dbg1hanya dipanggil saat startup. Ia menyadari bahwa tidak ada reactivekonteks (yang memang baru ditambahkan kemudian) dan karenanya tidak pernah mengingatnya. Dalam kasus dbg1itu melihat setidaknya satu reaktif dan dengan demikian kembali. Jadi saya rasa saya harus membuat l1reaktif sendiri (seperti yang ditunjukkan oleh @stefan)

Jawaban

2 stefan Oct 17 2020 at 04:01

Tidak yakin apa yang Anda coba capai pada akhirnya. Tetapi dengan mengikuti posting ini Anda dapat memperbarui daftar Anda dan mencetaknya dengan menggunakan reactiveValseperti ini:

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)

thothal Oct 19 2020 at 15:43

Saya kira masalahnya adalah ketika dbg1pemeriksaan pertama l1, tidak melihat konteks reaktif (yang benar). Namun, ia tidak menyadari bahwa pada l1akhirnya mengandung beberapa reactivesdan tidak pernah "mengingatnya".

Jadi, saya pikir kita harus lebih eksplisit l1dengan membuatnya menjadi reaktif itu sendiri (terinspirasi oleh @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())) 
}