闪亮的SelectInput和SelectizeInput

时间:2018-08-17 15:32:44

标签: r shiny selectize.js

我将Shiny库更新为1.1.0版,我注意到selectInput / selectizeInput和watchEvent / eventReactive的行为非常奇怪。

  1. 当我按退格键并清除下拉菜单的内容时,会出现问题。在以前的Shiny版本中,退格键与eventReactive结合使用,反应式表达式不会评估观察值(我认为将其视为NULL),而反应式会评估期望的结果。

  2. 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

这看起来不错,但是如果您注意到按下Backspace时renderTable仍在被调用。如果这是昂贵的计算,那将是不希望的行为。

    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)
  }
)

我想要的行为:当按退格键清除菜单时,未触发watchEvents和eventReactive。

1 个答案:

答案 0 :(得分:3)

似乎当前行为在退格键上触发了一个事件,但输入值保持不变。实际上,此行为可能是更新JavaScript函数Shiny.onInputChange时发生的意外更改。 NEWS on shinys github site在版本1.1下主张以下权利。

  

新功能

     

[...]

     

对(未公开但广泛使用的)JavaScript函数Shiny.onInputChange(name, value)进行了两项更改。首先,我们将函数名称更改为Shiny.setInputValue(但不用担心-旧的函数名称将继续起作用)。其次,直到现在,所有对Shiny.onInputChange(inputId, value)的呼叫均已“重复数据删除”;也就是说,只要将输入设置为已经具有的相同值,该设置就会被忽略。使用Shiny v1.1,您现在可以添加一个options对象作为第三个参数:Shiny.setInputValue("name", value, {priority: "event"})。将优先级选项设置为“事件”时,Shiny将始终发送该值并触发反应性,无论它是否重复。

当前版本的selectInput似乎利用了这个新的{priority: "event"}选项,但这只是猜测。

解决方法

您可以通过对输入进行重复数据消除来调整服务器代码,以正确处理此新行为。

dedupedValue <- reactiveVal()
observe({ dedupedValue(input$value) })

然后,在其余的服务器代码中使用dedupedValue()而不是input$value。这也适用于旧版本的Shiny。

注意::如果您尝试在上面的代码中使用reactive而不是observe,则无法使用。

长期解决方案

也许最好搁置此问题,直到有才华的开发人员查看your GitHub issue。如上所述,其原因可能是闪亮的JavaScript方面的接口更改。如果确实创建了代码突破性的更改,我相信开发人员将提供修复程序以确保向后兼容。

关于req

这基本上与当前问题无关,但提出了一个问题:如果您希望req在条件不是“真实”的情况下重新训练旧输出,则应将其命名为

req(condition, cancelOuput = TRUE)