Shiny移除最后选中项时observeEvent未触发的问题排查
问题:移除最后一个多选选项时Clear按钮无法自动隐藏
这是之前问题的后续,我想实现一个仅在有选中项时才显示的“Clear”按钮,用shinyjs写的代码如下:
require(shiny) require(shinyjs) ui <- fluidPage( shinyjs::useShinyjs(), # 用于显示/隐藏元素 shiny::selectizeInput( inputId="letters", label="Restrict to Letters:", choices=letters, selected=NULL, multiple = TRUE, options=list( placeholder="(all letters)" ) ), shinyjs::hidden(actionButton("clear","Clear")) # 初始隐藏 ) server <- function(input, output) { observeEvent(input$clear, { updateSelectizeInput(inputId = "letters", selected= "") shinyjs::hide(id="clear") }) observeEvent(input$letters, { # 移除最后一个选中项时不会触发 if(shiny::isTruthy(input$letters)) { message("length(input$letters)=", length(input$letters)) shinyjs::show(id="clear") } else { # 无选中项时 message("hiding clear button from oe(input$letters)") shinyjs::hide(id="clear") } }) } shinyApp(ui=ui, server=server)
问题现象:
点击Clear按钮时一切正常,控制台输出如下:
# Listening on http://127.0.0.1:5582 # length(input$letters)=1 # length(input$letters)=2 # length(input$letters)=3 # hiding clear button from oe(input$clear)
但如果选中几个选项后,用退格键逐个移除直到最后一项,Clear按钮会保持可见,控制台最后没有触发隐藏的日志:
# Listening on http://127.0.0.1:5582 # length(input$letters)=1 # length(input$letters)=2 # length(input$letters)=3 # length(input$letters)=2 # length(input$letters)=1 # (... and nothing else ...)
解决方案:
问题出在observeEvent(input$letters)的默认行为上——它默认ignoreNULL = TRUE,当最后一个选项被移除后,input$letters会变成NULL,此时观察者不会被触发。只需要给observeEvent加上ignoreNULL = FALSE参数,让它在input$letters为NULL时也能触发,就能自动隐藏Clear按钮了。
修改后的服务器端代码如下:
server <- function(input, output) { observeEvent(input$clear, { updateSelectizeInput(inputId = "letters", selected= "") shinyjs::hide(id="clear") }) observeEvent(input$letters, ignoreNULL = FALSE, # 关键:允许NULL值触发观察者 { if(shiny::isTruthy(input$letters)) { message("length(input$letters)=", length(input$letters)) shinyjs::show(id="clear") } else { message("hiding clear button from oe(input$letters)") shinyjs::hide(id="clear") } } ) }
这样无论通过Clear按钮清空,还是手动删到最后一项,Clear按钮都会正确隐藏。
内容的提问来源于stack exchange,提问作者Karsten W.
相关产品推荐
相关产品推荐

