Были две проблемы, которые необходимо было решить:
- ваше регулярное выражение
|c
перехвачено input$changed
- вам нужно использовать
isolate(names(input))
внутри выражения события, в противном случаенаблюдатель будет срабатывать при каждом изменении names(input)
- Редактировать: использовать
isolate({input$changed})
- см. комментарии (не требуется при использовании reactiveVal()
)
ui <- fluidPage(
tags$head(
tags$script(
"$(document).on('shiny:inputchanged', function(event) {
if (event.name != 'changed') {
Shiny.setInputValue('changed', event.name);
}
});"
)
),
numericInput("a_1", "a_1", 0),
textInput("a_2", "a_2"),
textInput("c", "c"),
textInput("d", "d"),
p("changedInputs:"), textOutput("changedInputs"), br(),
p("aFired:"), textOutput("aFired")
)
server <- function(input, output, session) {
output$changedInputs <- renderText({
paste("Outside observer: Latest input fired:", paste(input$changed, collapse = ", "))
})
observeEvent(eventExpr = {
lapply(grep(pattern = "^a_+[[:digit:]]$|^c$", x = isolate({names(input)}), value = TRUE), function(x){input[[x]]})
}, handlerExpr = {
req(input$changed)
if (input$changed == "a_1") {
output$aFired <- renderText("Inside observer: input$a_1 was fired")
} else if (input$changed == "a_2") {
output$aFired <- renderText("Inside observer: input$a_2 was fired")
} else {
output$aFired <- renderText({paste("Inside observer:", isolate({input$changed}), "was fired")})
}
}, ignoreInit = TRUE)
}
shinyApp(ui, server)
Другое редактирование: Теперь я помню, где потерялся isolate({input$changed})
(я был уверен, что он работал во время моих тестов ...) Изначально я подозревал, что renderText()
вложено внутрьНаблюдатель может вызвать проблемы, соответственно я реализовал reactiveVal()
для вывода на печать.Это решение работает без isolate({input$changed})
:
ui <- fluidPage(
tags$head(
tags$script(
"$(document).on('shiny:inputchanged', function(event) {
if (event.name != 'changed') {
Shiny.setInputValue('changed', event.name);
}
});"
)
),
numericInput("a_1", "a_1", 0),
textInput("a_2", "a_2"),
textInput("c", "c"),
textInput("d", "d"),
p("changedInputs:"), textOutput("changedInputs"), br(),
p("aFired:"), textOutput("aFired")
)
server <- function(input, output, session) {
output$changedInputs <- renderText({
paste("Outside observer: Latest input fired:", paste(input$changed, collapse = ", "))
})
myText <- reactiveVal()
observeEvent(eventExpr = {
lapply(grep(pattern = "^a_+[[:digit:]]$|^c$", x = isolate({names(input)}), value = TRUE), function(x){input[[x]]})
}, handlerExpr = {
req(input$changed)
if (input$changed == "a_1") {
myText("Inside observer: input$a_1 was fired")
} else if (input$changed == "a_2") {
myText("Inside observer: input$a_2 was fired")
} else {
myText(paste("Inside observer:", input$changed, "was fired"))
}
}, ignoreInit = TRUE)
output$aFired <- renderText({myText()})
}
shinyApp(ui, server)
Узнав о реальных проблемах и разместив здесь ответ, я вернулся к версии без reactiveVal()
(так как она ближе к вашему вопросу) изабыл isolate
.Соответственно вы получили смесь обеих версий в первую очередь.