繁体   English   中英

R Shiny:使用 htmlOutput 和 observeEvent 的不需要的反应

[英]R Shiny: unwanted reactivity using htmlOutput and observeEvent

问题总结

我已经彻底搜索过,我找不到任何问过同样问题的人。 我正在使用 R Shiny 制作化学反应模拟网页,并希望向用户显示最新模拟中的变量。 因此,用户可以更改输入变量,但在再次按下操作按钮并模拟另一个反应之前,显示的“变量摘要面板”不应更改。

使用 observeEvent、renderUI 和 htmlOutput 实现应该相当简单,但我一直遇到“变量摘要面板”对输入变量的变化做出反应的问题,即使没有按下操作按钮。 这是一些示例代码:

示例代码

library(shiny)
library(tidyverse)

ui <- fluidPage(
   # input variable
   tags$p("Reaction Temperature  (ºC)"),
   sliderInput("temp_initial",NULL,min = 20,max = 70,value = 25),
   # action button
   actionButton(inputId = "go", label = "Generate Reaction Simulation"),
   # summary panel
   wellPanel(
       tags$p(tags$strong("Simulated input variables")),
       htmlOutput("blurb_explanation")
   )
)
server <- function(input, output, session) {
    # render summary panel text
    observeEvent(input$go, ({
        output$blurb_explanation <- renderUI(
           HTML(paste("<strong>   Reaction Temperature (ºC) --></strong>", input$temp_initial))
        )
    })
    )
}
# Run the application 
shinyApp(ui = ui, server = server)

尝试的解决方案

我可能只是对 Shiny 反应性缺乏了解,因为我对 R Shiny 相当陌生。 我的理解是,如果我将 input$go 作为响应式表达式传递给 observeEvent,则 function 的主体将不会运行,直到再次按下 go 按钮。 现在,在创建摘要面板后,slider 中的任何更新仍然会更改 HTML output。

我已经尝试将 function 主体包装在隔离的 function 中,使 observeEvent 依赖于其他反应变量,但似乎没有什么可以解决这个反应性问题。

提前感谢您的帮助,这是我的第一个 Stack Overflow 问题,如果有任何不清楚的地方请告诉我,我可以尝试解决。

默认情况下,您的renderUI - 就像任何renderXXXX一样 - 更新以响应对其包含的任何响应式的更改。 因此,它会响应您的actionButtonsliderInput的点击而更新。 您无法摆脱它对sliderInput的依赖,因此您需要将sliderInput与对renderUI的更改isolate来。 幸运的是, isolate function 可以为您做到这一点。

这是您的服务器 function 的工作版本:

server <- function(input, output, session) {
  # render summary panel text
  observeEvent(input$go, ({
    output$blurb_explanation <- renderUI(
      isolate(HTML(paste("<strong>   Reaction Temperature (ºC) --></strong>", input$temp_initial)))
    )
  })
  )
}

更简单的版本将不再需要renderUIobserveEvent

server <- function(input, output, session) {
  # render summary panel text
    output$blurb_explanation <- renderText({
      input$go
      isolate(HTML(paste("<strong>   Reaction Temperature (ºC) --></strong>", input$temp_initial)))
    })
}

renderText仍然依赖于actionButton ,因此它会随着按钮的点击而更新。 但是actionButton生成 output。 htmlOutputsliderInput的依赖仍然被isolate所掩盖,因此 output 仅更新按钮点击。

PS。 欢迎来到 SO。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM