注意:在提出答案后,我重新提出问题,以便更清楚。
有时在shiny
应用中。我想使用用户为窗口小部件选择的值,以及为该窗口小部件选择的先前值。这可以应用于从用户输入派生的反应值,其中我想要旧值和新值。
问题在于,如果我尝试保存窗口小部件的值,那么包含该值的变量必须是被动的,或者每次窗口小部件更改时都不会更新。但是,如果我将值保存在被动上下文中,它将始终为我提供当前值,而不是前一个值。
如何保存窗口小部件的先前值,但每次用户更改窗口小部件时仍会更新?
每次用户更改内容时,是否有一种方法不需要使用actionButton
?避免使用actionButton
可能是合乎需要的,否则添加一个是不必要的,并为用户创建多余的点击。
答案 0 :(得分:8)
更新此答案是在reactiveValues
observeEvent
/ shiny
模型出现之前发布的。我认为@MikeWise的答案是更好的方法。
经过一番游戏后,我想出了这个。 ui.r没什么特别的
ui.r
library(shiny)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
selectizeInput(inputId="XX", label="Choose a letter",choices=letters[1:5])
),
mainPanel(
textOutput("Current"),
textOutput("old")
)
)
))
"Current"
将显示当前选择,"old"
显示上一个选择。
在server.r
我使用了三个关键功能:reactiveValues
,isolate
和session$onFlush
。
server.r
library(shiny)
server <- function(input, output,session) {
Values<-reactiveValues(old="Start")
session$onFlush(once=FALSE, function(){
isolate({ Values$old<-input$XX })
})
output$Current <- renderText({paste("Current:",input$XX)})
output$old <- renderText({ paste("Old:",Values$old) })
}
server.r
就像这样。
首先,使用Values$old
函数创建reactiveValues
。我给了它价值&#34;开始&#34;明确加载时发生的事情。
然后我添加了session$onFlush
功能。请注意,我在session
函数中将server
作为参数。每当闪亮的反应系统冲洗时,这将运行 - 例如当用户更改selectizeInput
时。重要的是,它会在input$XX
获得新值之前运行 - 因此值已在selectizeInput
处更改,但未在XX
处更改。
在session$onFlush
内,我将XX
的传出值分配给Values$old
。这是在isolate()
内完成的,因为这可以防止使用新值更新input$XX
的任何问题。然后,我可以在input$XX
函数中使用Values$old
和renderText()
。
答案 1 :(得分:6)
由于会话刷新事件方法似乎为此目的而被破坏,因此这是使用observeEvent
构造和反应变量的替代方法。
library(shiny)
ui <- fluidPage(
h1("Memory"),
sidebarLayout(
sidebarPanel(
numericInput("val", "Next Value", 10)
),
mainPanel(
verbatimTextOutput("curval"),
verbatimTextOutput("lstval")
)
)
)
server <- function(input,output,session) {
rv <- reactiveValues(lstval=0,curval=0)
observeEvent(input$val, {rv$lstval <- rv$curval; rv$curval <- input$val})
curre <- reactive({req(input$val); input$val; rv$curval})
lstre <- reactive({req(input$val); input$val; rv$lstval})
output$curval <- renderPrint({sprintf("cur:%d",curre())})
output$lstval <- renderPrint({sprintf("lst:%d",lstre())})
}
options(shiny.reactlog = TRUE)
shinyApp(ui, server)
产量: