如何在Shiny observeEvent中监听多个事件表达式

Kip*_*čys 8 r shiny shiny-reactivity

我想要两个不同的事件来触发观察者.这里有人建议这应该有效.但它似乎只取决于第二个事件.

observeEvent({ 
  input$spec_button
  mainplot.click$click
}, { ... } )
Run Code Online (Sandbox Code Playgroud)

看看这个例子.

ui <- shinyUI(bootstrapPage(
    actionButton("test1", "test1"),
    actionButton("test2", "test2"))
)

server <- shinyServer(function(input, output) {
    observeEvent({
        input$test1
        input$test2
    }, {
        print('Hello World')
    })
})

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

一旦你点击按钮test1没有任何反应.如果单击按钮test2,它将打印到您的控制台.按下test2按钮后,单击test1打印消息.这是一种奇怪的行为.

链接的另一个建议是使用

list(input$test1, input$test2)
Run Code Online (Sandbox Code Playgroud)

即使不单击按钮,也会打印消息.

Gio*_*tti 20

如果输入不是数字、逻辑或复杂类型,则|在 中使用运算符将​​不起作用。observeEvent() eventExpr

例如,请注意运行这个简单的 Shiny 应用程序结束时的消息,其中使用了anactionButton() a :selectInput()observeEvent() eventExpr

library(shiny)

ui <- shinyUI(bootstrapPage(
  selectInput("test1", "test1", choices = c("a", "b")),
  actionButton("test2", "test2"))
)

server <- shinyServer(function(input, output) {
  
  observeEvent(input$test1 | input$test2,
  {
    print('Hello World')
  })
})

shinyApp(ui, server)
#> 
#> Listening on http://127.0.0.1:6563
#> Warning: Error in |: operations are possible only for numeric, logical or
#> complex types
Run Code Online (Sandbox Code Playgroud)

由reprex 包于 2022 年 4 月 2 日创建(v2.0.1)

相反,如果您不希望在应用程序初始化时打印“​​Hello World”,您可以在observeEvent()和 include中创建输入列表。ignoreInit = TRUE这种方法适用于任何输入类型。

library(shiny)
ui <- shinyUI(bootstrapPage(
  selectInput("test1", "test1", choices = c("a", "b")),
  actionButton("test2", "test2"))
)

server <- shinyServer(function(input, output) {
  
  observeEvent(ignoreInit = TRUE, list(
    input$test1,
    input$test2
  ),
  {
    print('Hello World')
  })
})

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

如果这种observeEvent(list(input$a, input$b), {...})方法不能让你的船漂浮,那么我可以推荐reactive({list(input$a, input$b})这样的方法:

library(shiny)
ui <- shinyUI(bootstrapPage(
  selectInput("test1", "test1", choices = c("a", "b")),
  actionButton("test2", "test2"))
)

server <- shinyServer(function(input, output) {
  
  event_trigger <- reactive({
    list(input$test1, input$test2)
  })
  
  observeEvent(ignoreInit = TRUE, event_trigger(),
  {
    print('Hello World')
  })
})

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是可移植,这意味着如果需要,您可以将其用作eventExpr多个observeEvent()调用(或其他侦听器)。


Por*_*hop 7

这应该这样做,请注意你仍然需要检查按钮是否被@MrFlick提到点击了

你可以使用反应性表达

#rm(list = ls())
library(shiny)
ui <- shinyUI(bootstrapPage(
  actionButton("test1", "test1"),
  actionButton("test2", "test2"))
)

server <- shinyServer(function(input, output) {

  toListen <- reactive({
    list(input$test1,input$test2)
  })
  observeEvent(toListen(), {
    if(input$test1==0 && input$test2==0){
      return()
    }
    print('Hello World')
  })
})

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

2.按照@MrFlick给出的示例(现已删除)

#rm(list = ls())
library(shiny)
ui <- shinyUI(bootstrapPage(
  actionButton("test1", "test1"),
  actionButton("test2", "test2"))
)

server <- shinyServer(function(input, output) {

  observeEvent(input$test1 | input$test2, {
    if(input$test1==0 && input$test2==0){
      return()
    }
    print('Hello World')
  })
})

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

  • 不,不是,再次复制并粘贴此代码 (2认同)
  • 如果输入不是“actionButton()”而是“selectInput()”,#2 将不起作用。 (2认同)