R Shiny 仅观察特定的 reactiveVal 变化

R Shiny observe only a specific reactiveVal change

是否可以让 observe 函数仅在特定 reactiveVal 更改时触发?

在我的所有带有反应式和观察者的代码交叉引用模块中,我有一些东西可以归结为以下玩具示例:

library(shiny)

shinyApp(
  fluidPage(
    textInput('i1', 'Input 1'),
    textInput('i2', 'Input 2'),
    textInput('out', 'Output (do not edit)')
  ),
  function(input, output, session) {
    observe({ print(input$i2); updateTextInput(session, 'out', value = input$i1) })
    observe({ print(input$i1); updateTextInput(session, 'out', value = input$i2) })
  }
)

请注意,如果没有打印语句,代码将按我希望的方式运行。但是,如果两个观察者都使用两个输入,则两个观察者都按顺序触发,并且只有来自第二个观察者的 input$i2 被放入我的 out textInput.

有什么方法可以让我告诉 shiny 我只想在 input$i1 更改时将第一个 observe 更改为 运行,而第二个 observe 更改为 运行 当 input$i2 改变时?

编辑

事实证明,您可以在输入上使用 observeEvent 来区分它们。但是,在现在更复杂的示例中,我无法在 reactiveVal 上使用 observeEvent - 在这种情况下它根本不会触发。同样,以下示例在没有 print 语句的情况下也能正常工作,但使用它时两个观察者都会触发。

有没有办法观察reactiveVal的变化?

library(shiny)

shinyApp(
  fluidPage(
    textInput('i1', 'Make uppercase'),
    textInput('i2', 'Make lowercase'),
    textInput('out', 'Output (ideally not editable)')
  ),
  function(input, output, session) {
    i1 <- reactiveVal('')
    i2 <- reactiveVal('')

    observeEvent(input$i1, { i1(toupper(input$i1)) })
    observeEvent(input$i2, { i2(tolower(input$i2)) })

    observe({ print(i2()); updateTextInput(session, 'out', value = i1()) })
    observe({ print(i1()); updateTextInput(session, 'out', value = i2()) })
  }
)

observeEvent 确实适用于任何反应式上下文,这里是它如何与 reactiveVal

一起使用的示例
library(shiny)

shinyApp(
  fluidPage(
    textInput('i1', 'Make uppercase'),
    textInput('i2', 'Make lowercase'),
    textInput('out', 'Output (ideally not editable)')
  ),
  function(input, output, session) {
    i1 <- reactiveVal('')
    i2 <- reactiveVal('')
    
    observeEvent(input$i1, { i1(toupper(input$i1)) })
    observeEvent(input$i2, { i2(tolower(input$i2)) })
    
    observeEvent(i1(), {print(i2()); updateTextInput(session, 'out', value = i1()) })
    observeEvent(i2(), {print(i1()); updateTextInput(session, 'out', value = i2()) })
  }
)