R闪亮:使用htmlOutput和observeEvent

时间:2020-07-27 17:46:45

标签: r shiny shiny-reactivity

问题摘要

我已经进行了彻底的搜索,但是找不到有人问过同样的问题。我正在使用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)

尝试的解决方案

由于我对R Shiny相当陌生,所以我可能对Shiny反应性缺乏了解。我的理解是,如果我将input $ go作为反应性表达式传递给observeEvent,则函数主体将不会运行,直到再次按下go按钮。现在,在完成“摘要”面板后,滑块中的所有更新仍会更改HTML输出。

我尝试将函数体包装在一个隔离函数中,使observeEvent依赖于其他反应性变量,似乎没有任何方法可以解决此反应性问题。

在此先感谢您的帮助,这是我的第一个堆栈溢出问题,如果有任何不清楚的地方,请告诉我,我可以尝试解决。

1 个答案:

答案 0 :(得分:1)

默认情况下,您的renderUI(与任何renderXXXX一样)会更新,以响应对 any 的更改(如果其中包含的反应堆)。因此,它会随着您的actionButtonsliderInput的点击而更新。您无法摆脱其对sliderInput的依赖性,因此您需要isolate renderUI才能更改sliderInput。幸运的是,isolate函数为您做到了。

这是服务器功能的有效版本:

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不产生任何输出。 htmlOutputsliderInput的依赖仍然被isolate掩盖,因此输出仅更新为按钮单击。

PS。欢迎来到SO。