获取在Shiny和grep中触发的事件(生成的输入)

时间:2019-06-26 15:22:27

标签: r events shiny

我已经生成了_1,_2等输入,但是我想知道触发了哪个事件。

但是两者都不起作用,.clientdata_output_aFired_hiddend被解雇了。在我的真实应用中,其他隐藏或与反应性值关联的事件也会触发。

在没有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 = ", "))
  })

  observeEvent({
    lapply(
      (grep(pattern = "a_+[[:digit:]]|c"
      , x = names((input)), value = TRUE)),
      function(x) (input)[[x]]
    )
  }, {
    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((input$changed))
    }
  }, ignoreInit = TRUE)
}

shinyApp(ui, server)

1 个答案:

答案 0 :(得分:1)

有两个问题需要解决:

  1. 您的正则表达式|cinput$changed捕获了
  2. 您需要在事件表达式中使用isolate(names(input)),否则观察者将为names(input)的每次更改触发
  3. 编辑:使用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。因此,您首先收到了两种版本的混合版本。