问题摘要
我已经进行了彻底的搜索,但是找不到有人问过同样的问题。我正在使用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依赖于其他反应性变量,似乎没有任何方法可以解决此反应性问题。
在此先感谢您的帮助,这是我的第一个堆栈溢出问题,如果有任何不清楚的地方,请告诉我,我可以尝试解决。
答案 0 :(得分:1)
默认情况下,您的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。