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,函数的主体将不会 运行 直到再次按下 go 按钮。现在,在创建摘要面板后,滑块中的任何更新仍会更改 HTML 输出。
我试过将函数体包装在一个隔离函数中,使 observeEvent 依赖于其他反应变量,但似乎没有什么可以解决这个反应问题。
提前感谢您的帮助,这是我的第一个 Stack Overflow 问题,如果有任何不清楚的地方,请告诉我,我可以尝试修复。
默认情况下,您的 renderUI
- 就像任何 renderXXXX
- 更新以响应对 any 的更改,如果它包含反应。因此它会响应您对 actionButton
和 sliderInput
的点击而更新。你无法摆脱它对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)))
)
})
)
}
更简单的版本将不再需要 renderUI
或 observeEvent
:
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
没有输出。 htmlOutput
对 sliderInput
的依赖性仍被 isolate
掩盖,因此输出仅更新为按钮点击。
PS。欢迎来到 SO。
问题总结
我已经彻底搜索过了,但找不到任何人问过同样的问题。我正在使用 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,函数的主体将不会 运行 直到再次按下 go 按钮。现在,在创建摘要面板后,滑块中的任何更新仍会更改 HTML 输出。
我试过将函数体包装在一个隔离函数中,使 observeEvent 依赖于其他反应变量,但似乎没有什么可以解决这个反应问题。
提前感谢您的帮助,这是我的第一个 Stack Overflow 问题,如果有任何不清楚的地方,请告诉我,我可以尝试修复。
默认情况下,您的 renderUI
- 就像任何 renderXXXX
- 更新以响应对 any 的更改,如果它包含反应。因此它会响应您对 actionButton
和 sliderInput
的点击而更新。你无法摆脱它对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)))
)
})
)
}
更简单的版本将不再需要 renderUI
或 observeEvent
:
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
没有输出。 htmlOutput
对 sliderInput
的依赖性仍被 isolate
掩盖,因此输出仅更新为按钮点击。
PS。欢迎来到 SO。