Mam to, co myślę, że jest całkiem prostym przypadkiem użytkownika, dla którego nie byłem w stanie znaleźć rozwiązania: Chcę, aby Shiny generował określoną przez użytkownika liczbę wejść, dynamicznie tworząc obserwator dla każdego.Generowanie obserwatorów dla dynamicznej liczby wejść
W poniższym minimalnym odtwarzalnym kodzie użytkownik wskazuje liczbę przycisków czynności, które chce się wprowadzić, wpisując do widżetu textInput
; następnie naciska przycisk "submit", który generuje przyciski akcji.
Co chcę jest dla użytkownika, aby następnie móc kliknąć na dowolny przycisk akcji i generuje wyjście specyficzne dla niego (np minimalnej przypadku, po prostu wydrukować nazwę przycisk):
library("shiny")
ui <- fluidPage(textInput("numButtons", "Number of buttons to generate"),
actionButton("go", "Submit"), uiOutput("ui"))
server <- function(input, output) {
makeObservers <- reactive({
lapply(1:(as.numeric(input$numButtons)), function (x) {
observeEvent(input[[paste0("add_", x)]], {
print(paste0("add_", x))
})
})
})
observeEvent(input$go, {
output$ui <- renderUI({
num <- as.numeric(isolate(input$numButtons))
rows <- lapply(1:num, function (x) {
actionButton(inputId = paste0("add_", x),
label = paste0("add_", x))
})
do.call(fluidRow, rows)
})
makeObservers()
})
}
shinyApp(ui, server)
Problem z powyższym kodem polega na tym, że w jakiś sposób tworzonych jest kilku obserwatorów, ale wszystkie jako ostatni przyjmują tylko ostatni element z listy przekazany do lapply
. Więc jeśli wygeneruję cztery przyciski akcji i kliknę przycisk akcji # 4, Shiny wypisuje swoją nazwę cztery razy, podczas gdy wszystkie pozostałe przyciski nie reagują.
Pomysł wygenerować obserwatorów stosując lapply
pochodzi z https://github.com/rstudio/shiny/issues/167#issuecomment-152598096
Jest to tylko uwaga, że kwestia generowania obserwatorów tylko na ostatniej pozycji na liście przeszłości do „lapply” był jednym z kompatybilności pomiędzy błyszczące i wersja R które zainstalowałem. W najnowszej wersji R mój przykładowy kod zachowuje się tak, jak w poniższej odpowiedzi mówi, że tak, a oferowane rozwiązanie działa. –