如何在一个闪亮事件中监听多个事件表达式


85

我想要两个不同的事件来触发我的应用程序中各种绘图/输出所使用的数据的更新。一个是被单击的按钮(input$spec_button),另一个是被单击的点上的点(mainplot.click$click)。

基本上,我想同时列出两者,但是我不确定如何编写代码。这是我现在拥有的:

在server.R中:

data <- eventReactive({mainplot.click$click | input$spec_button}, {
    if(input$spec_button){
      # get data relevant to the button
    } else {
      # get data relevant to the point clicked
    }
  })

但是if-else子句不起作用

Error in mainplot.click$click | input$spec_button : operations are possible only for numeric, logical or complex types

->我可以为mainplot.click$click | input$spec_button子句使用某种动作组合功能吗?


您可以检查!is.null(input $ spec_button)的输出吗?
Gopala'1

Answers:


94

我知道这很老,但是我有同样的问题。我终于弄明白了。您可以在括号中包含一个表达式,然后简单地列出事件/反应对象。我的(未经证实的)猜测是,shiny只是对该表达式块执行与标准reactive块相同的反应性指针分析。

observeEvent({ 
  input$spec_button
  mainplot.click$click
  1
}, { ... } )

编辑

更新以处理表达式的最后一行返回NULL的情况。只需返回一个常数即可。


1
更改对此答案的可接受答案,因为它似乎比我的原始解决方案更好。
希拉里·桑德斯

3
您能否确定触发了哪个事件?
PeterVermont

不是我知道的。在某些情况下,我通过在单独的变量中跟踪它们并自己进行比较以查看哪个发生了变化来完成此操作。但这很丑。最好将主代码放在函数中,然后有两个调用fn的observeEvent,然后为每个事件做特定的事情。
邓肯·布朗

8
只是警告:默认情况下observeEvent使用ignoreNULL = TRUE,这意味着mainplot.click$click(返回值)为时NULL,即使更改处理程序也不会被调用input$spec_button。我建议使用类似@JustAnother的答案,以防止陷入该陷阱。
greg L

1
另一个警告:在测试中,我发现此括号语法({})要求每个事件都位于其自己的换行符上,否则,当解析器遇到第二个事件时,它将失败并显示“解析错误...”。例如,全部一行:observeEvent({input$spec_button mainplot.click$click}, {...})失败。@JustAnother使用S3通用组合语法(c())的答案与换行符无关。
布赖恩D

54

也:

observeEvent(c( 
  input$spec_button,
  mainplot.click$click
), { ... } )

6
尽管这看起来与@DuncanBrown的答案非常相似,但我发现一种情况,其中2个操作按钮都触发了一个模式,但这种方法有效,而{版本却没有。我无法解释为什么会这样。
约翰·保罗

2
在@Duncan Brown的答案中添加了注释,说明此答案有何不同(以及更好的IMO)
greg L

这对我不起作用-我收到一个错误(闪亮1.0.5)
potockan18年

有没有办法找出触发了哪个事件?可以说我有两个按钮,input$button1并且input$button2该做的非常类似的事情,只是用不同的指标。我想避免仅仅因为我不知道索引而多次复制代码。谢谢!
Nikos Bosse

10

我已经通过创建反应式对象并将其用于事件更改表达式中来解决了此问题。如下:

xxchange <- reactive({
paste(input$filter , input$term)
})

output$mypotput <- eventReactive( xxchange(), {
...
...
...
} )

4
这是一个很好的答案,可以从更多的解释中受益。虽然可接受的答案更直接,使其更适合基本程序,但此答案更适合于大型和复杂的代码。答案似乎缺少两点(1)粘贴(或列表)将两个事件放在同一行上,使代码更紧凑。(2)如果一个以上的侦听器正在侦听同一事件集,则反应式对象可以省去一遍又一遍地重复相同的两个事件。
农业

5

这是我想出的解决方案:基本上,创建一个空的reactiveValues数据保存器,然后根据两个单独的observeEvent实例修改其值。

  data <- reactiveValues()
  observeEvent(input$spec_button, {
    data$data <- get.focus.spec(input=input, premise=premise, 
                                itemname=input$dropdown.itemname, spec.info=spec.info)
  })
  observeEvent(mainplot.click$click, {
    data$data <- get.focus.spec(input=input, premise=premise, mainplot=mainplot(),
                                mainplot.click_focus=mainplot.click_focus(),
                                spec.info=spec.info)  
  })

3
list(mainplot.click$click, input$spec_button)也将按照OP的方式工作。
约翰


0

这里的想法是创建一个反应函数,该函数将执行您要在observeEvent中传递的条件,然后可以传递此反应函数来检查语句的有效性。例如:

validate_event <- reactive({
    # I have used OR condition here, you can use AND also
    req(input$spec_button) || req(mainplot.click$click)
})

observeEvent(validate_event(), 
    { ... } 
)

继续编码!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.