在 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))
})
}
我正在尝试使用 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))
})
}