Shiny中shinyjs::reset执行后input值未更新的问题求助
问题描述
开发Shiny应用时,切换working选项为"No"后,调用shinyjs::reset("occupation")无法重置服务器端的input$occupation值,打印结果仍保留之前选择的职业值,不符合预期。
可复现代码
library(shiny) library(shinyjs) #> #> Attaching package: 'shinyjs' #> The following object is masked from 'package:shiny': #> #> runExample #> The following objects are masked from 'package:methods': #> #> removeClass, show ui <- fluidPage( useShinyjs(), selectInput("working", "Working", choices = c("Select" = "", "Yes", "No")), conditionalPanel( condition = "input.working == 'Yes'", uiOutput("dynamicOccupationQuestion") ) ) server <- function(input, output, session) { output$dynamicOccupationQuestion <- renderUI({ req(input$working) if (input$working == "Yes") { selectInput( "occupation", "What is your current occupation?", choices = c("Write down your occupation" = "", "Manager"), selectize = TRUE, width = "100%" ) } }) observe({ if (input$working == "No") { print("Resetted input") reset("occupation") } print("Current occupation") print(input$occupation) }) } shinyApp(ui = ui, server = server)
当前输出
[1] "Current occupation" NULL [1] "Current occupation" NULL [1] "Current occupation" [1] "" [1] "Current occupation" [1] "Manager" [1] "Resetted input" [1] "Current occupation" [1] "Manager"
预期输出
[1] "Current occupation" NULL [1] "Current occupation" NULL [1] "Current occupation" [1] "" [1] "Current occupation" [1] "Manager" [1] "Resetted input" [1] "Current occupation" [1] ""
原因分析
- 当
conditionalPanel的条件不满足时,occupation对应的UI元素会从DOM中移除,shinyjs::reset()是基于DOM元素的操作,此时找不到目标元素,无法触发服务器端input$occupation的更新。 - Shiny的input值仅在UI元素存在于DOM中时,才会将客户端值同步到服务器端;元素隐藏后,服务器端的input值会保留之前的状态。
解决方案
使用updateSelectInput()直接更新服务器端的input$occupation值,该方法通过Shiny的session通信机制生效,不受UI元素是否存在的影响。
修改后的完整代码:
library(shiny) library(shinyjs) ui <- fluidPage( useShinyjs(), selectInput("working", "Working", choices = c("Select" = "", "Yes", "No")), conditionalPanel( condition = "input.working == 'Yes'", uiOutput("dynamicOccupationQuestion") ) ) server <- function(input, output, session) { output$dynamicOccupationQuestion <- renderUI({ req(input$working) if (input$working == "Yes") { selectInput( "occupation", "What is your current occupation?", choices = c("Write down your occupation" = "", "Manager"), selectize = TRUE, width = "100%" ) } }) observe({ if (input$working == "No") { print("Resetted input") # 替换reset为updateSelectInput,直接更新服务器端input值 updateSelectInput(session, "occupation", selected = "") } print("Current occupation") print(input$occupation) }) } shinyApp(ui = ui, server = server)
验证结果
运行修改后的代码,切换working为"No"后,打印结果会显示input$occupation被重置为"",完全符合预期。
内容的提问来源于stack exchange,提问作者cimentadaj
相关产品推荐
相关产品推荐

