Я обновил свою библиотеку Shiny до версии 1.1.0 и заметил очень странное поведение с selectInput / selectizeInput и ObservationEvent / eventReactive.
Проблема возникает, когда я нажимаю клавишу возврата и очищаю содержимое раскрывающегося меню. В предыдущей версии Shiny обратное пространство в сочетании с eventReactive, реактивное выражение не оценивало (я предполагаю, что оно рассматривало это как NULL), наблюдаемое, а реактивное оценивало бы то, что требуется.
req () также ведет себя странно: в примере 1 ниже, если мы нажимаем клавишу возврата и очищаем ввод, запускается renderTable, но когда req (input $ variable) пуст, таблица исчезает. В предыдущей версии, если Shiny, я считаю, что таблица просто останется прежней.
Воспроизведение кода:
Пример 1
shinyApp(
ui = fluidPage(
selectizeInput("variable", "Variable:",
c("Cylinders" = "cyl",
"Transmission" = "am",
"Gears" = "gear")),
tableOutput("data")
),
server = function(input, output) {
observeEvent(input$variable,{
cat("Printing: ",input$variable,"\n")
})
output$data <- renderTable({
req(input$variable)
Sys.sleep(2)
mtcars[, c("mpg", input$variable), drop = FALSE]
}, rownames = TRUE)
}
)
или
Пример 2
Это выглядит нормальным поведением, но если вы заметили, что renderTable все еще вызывается при нажатии клавиши Backspace. Если бы это было дорогостоящее вычисление, это было бы нежелательным поведением.
shinyApp(
ui = fluidPage(
selectInput("variable", "Variable:",
c("Cylinders" = "cyl",
"Transmission" = "am",
"Gears" = "gear")),
tableOutput("data")
),
server = function(input, output) {
observeEvent(input$variable,{
cat("Printing: ",input$variable,"\n")
})
output$data <- renderTable({
req(input$variable)
Sys.sleep(2)
mtcars[, c("mpg", input$variable), drop = FALSE]
}, rownames = TRUE)
}
)
Мое желаемое поведение: когда нажата клавиша Backspace, чтобы очистить меню, наблюдаемые события и eventReactive не запускаются.





Похоже, что текущее поведение запускает событие на backspace, но входное значение остается прежним. На самом деле такое поведение могло быть непреднамеренным изменением, которое произошло при обновлении функции JavaScript Shiny.onInputChange. НОВОСТИ на сайте shinys github утверждает следующее в Версии 1.1.
NEW FEATURES
[...]
Introduced two changes to the (undocumented but widely used) JavaScript function
Shiny.onInputChange(name, value). First, we changed the function name toShiny.setInputValue(but don't worry--the old function name will continue to work). Second, until now, all calls toShiny.onInputChange(inputId, value)have been "deduplicated"; that is, anytime an input is set to the same value it already has, the set is ignored. With Shiny v1.1, you can now add an options object as the third parameter:Shiny.setInputValue("name", value, {priority: "event"}). When the priority option is set to "event", Shiny will always send the value and trigger reactivity, whether it is a duplicate or not.
Текущая версия selectInput, похоже, использует преимущества этой новой опции {priority: "event"}, но это только предположения.
Вы можете адаптировать свой серверный код для правильной обработки этого нового поведения путем дедупликации входных данных самостоятельно.
dedupedValue <- reactiveVal()
observe({ dedupedValue(input$value) })
Затем вы используете dedupedValue() вместо input$value в остальной части вашего серверного кода. Это также будет работать со старыми версиями shiny.
ПРИМЕЧАНИЕ: Если вы попытаетесь использовать reactive вместо observe в приведенном выше коде, это не сработает.
Может быть, лучше отложить этот вопрос, пока блестящие разработчики не взглянут на ваша проблема с GitHub. Как указывалось выше, причиной этого, вероятно, является изменение интерфейса на стороне JavaScript на shiny. Если это действительно привело к критическим изменениям кода, я уверен, что разработчики предоставят исправление для обеспечения обратной совместимости.
reqЭто в основном не связано с рассматриваемой проблемой, но возник вопрос: если вы хотите, чтобы req переобучал старый вывод, если условие не является «истинным», вы должны назвать его как
req(condition, cancelOuput = TRUE)