在 Shiny R 中实现相互依赖的对象的正确方法是什么?

What is the correct way to implement objects that depend on each others change in Shiny R?

我正在尝试使用 Shiny。我习惯了其他编程语言(来自 App Development 的 Java 的一点点),其中有 onClick 事件,触发其他变量的变化。我知道在 MVC 中,在视图元素发生变化后,控制器可以在后台更改模型变量,然后更新视图,而不会触发其他元素上的事件无限循环。

此处的代码有效,但它触发了不必要的循环:

如果你选择49作为n,那么几十就变成了4,n就变成了48,几十就变成了4,这不会触发变化事件。

如果您随后将 n 更改为 49,则数十次更改为 4,这不会触发更改事件。

看起来很浪费资源..

library(shiny)

ui <- fluidPage(
  sliderInput(inputId = "dozens",
              label = "Dozens:",
              min = 1,
              max = 5,
              value = 2),
  sliderInput(inputId = "n",
              label = "n:",
              min = 1,
              max = 60,
              value = 24)
)
server <- function(input, output,session) {
  observeEvent(input$dozens,{
    updateSliderInput(session,"n",value=12*input$dozens)
  })
  observeEvent(input$n,{
    updateSliderInput(session,"dozens",value=round(input$n/12))
  })
}

shinyApp(ui = ui, server = server)

正确的方法是什么?

observeEvent 是(某种)Shiny 中的反模式。不要误会我的意思,它非常有用,不可或缺,我一直都在使用它。但是反应性通常在 Shiny 中工作得更好,因为不关心它并且只以描述性的方式编写计算。

不过,在 OP 的情况下,我同意这似乎是不可能的。
输入之间的循环依赖尤其棘手。

一个不通用但适用于 OP 的解决方案是添加一个简单的 if():

server <- function(input, output, session) {
  observeEvent(input$dozens, {
    if (round(input$n / 12) != input$dozens) {
      updateSliderInput(session, "n", value = 12 * input$dozens)
    }
  })

  observeEvent(input$n, {
    updateSliderInput(session, "dozens", value = round(input$n / 12))
  })
}