我想知道当输入字段基于另一个输入字段自动更新时如何使用bookmarkButton
恢复输入字段。请参见以下代码作为示例。也请使用此链接(https://yuchenw.shinyapps.io/Bookmark_Recovery/)访问此应用。
library(shiny)
# Define UI
ui <- function(request){
fluidPage(
# A select menu to select the car name
selectInput(inputId = "Select_Car", label = "Select a car", choices = row.names(mtcars)),
# A numeric input for mpg
# It will be automatically updated based on the car selected
# But users can also provided a numbers
numericInput(inputId = "MPG", label = "The mpg of the car", value = NA),
# Bookmark button to save the current state of the app
bookmarkButton()
)
}
# Define Server
server <- function(input, output, session){
# Reactive function to get the mpg based on car name
car_mpg <- reactive({
req(input$Select_Car)
return(mtcars[row.names(mtcars) %in% input$Select_Car, "mpg"])
})
# Update the MPG input
observeEvent(input$Select_Car, {
updateNumericInput(session, "MPG", value = car_mpg())
})
}
# Enable bookmarking
shinyApp(ui, server, enableBookmarking = "url")
此示例包含两个输入字段。第一个是selectInput
,可以允许用户从ntcars
数据集中选择汽车名称。第二个是numericInput
,用户可以指定汽车的mpg
。如果使用selectInput
选择了汽车名称,则关联的mpg
值将自动更新为numericInput
。最后,有一个bookmarkButton
用于保存输入值。
我发现,如果bookmarkButton的编号与关联的汽车名称numericInput
的编号不同,则bookmarkButton无法恢复mpg
中的值。例如,如果我在Valiant
中选择selectInput
,则mpg
为18.1
,并且更新为numericInput
。 bookmarkButton
将为我生成以下URL,以恢复该应用。
如果将URL复制并粘贴到浏览器中,则会看到类似于屏幕截图的内容。
这很好。但是现在假设我知道mpg
的{{1}}变成了Valiant
,而不是20
,所以我将18.1
的值更改为numericInput
,例如下面的屏幕截图。
如果我点击20
,则URL为:
尽管如此,如果我们单击此URL,则bookmarkButton
的恢复输入值为mpg
而不是18.1
。
我知道这与20
有关,因为我要求应用基于updateNumericInput
更新numericInput
。有没有办法要求selectInput
将bookmarkButton
还原为mpg
,而不是20
?
答案 0 :(得分:2)
问题在于,在创建反应式(即关联事件处理程序时)时,它正在运行。值(通过浏览器)已正确设置为您在URL中传递的任何值(请注意,书签会生成正确的URL),但是在创建处理程序时将更改它们。
解决方案是将ignoreInit=TRUE
传递给observeEvent
,以使其在创建时不运行处理程序(从而保持URL传递的值)。
# ...
server <- function(input, output, session){
# Reactive function to get the mpg based on car name
car_mpg <- reactive({
req(input$Select_Car)
return(mtcars[row.names(mtcars) %in% input$Select_Car, "mpg"])
})
# Update the MPG input
observeEvent(input$Select_Car, {
updateNumericInput(session, "MPG", value = car_mpg())
}, ignoreInit=TRUE) # notice the parameter has been passed here.
}
# ...