如何基于已选内容更新Shiny中selectizeInput的选项?
解决SelectizeInput更新循环的问题
你遇到的循环问题其实很典型——每次调用updateSelectizeInput更新选项时,哪怕选中的值没变化,也会触发input$words的监听事件,进而再次执行更新逻辑,形成“监听变化→更新选项→触发变化→再监听”的无限循环。要解决这个问题,我们需要加一层判断,只有当新生成的可选选项和当前的不一样时,才执行更新操作,从根源上切断循环。
这里给你一个稳妥的修正方案:
用reactiveVal跟踪当前选项集合
通过reactiveVal存储当前的可选选项,每次生成新选项后先和已有值对比,确认不一样再更新UI,避免无意义的重复触发:
library(shiny) run_ui <- function() { ui <- selectizeInput('words', 'Search words:', choices = NULL, selected = NULL, multiple = TRUE, options = NULL) server <- function(input, output, session) { # 用reactiveVal存储当前的可选选项,初始值为字母表 current_choices <- reactiveVal(letters) # 监听选中内容的变化 observeEvent(input$words, { # 根据选中内容生成新的可选选项 if (is.null(input$words)) { new_choices <- letters } else { new_choices <- unique(c(input$words, sample(letters, 5))) } # 只有当新选项和当前选项不一样时才执行更新 if (!identical(new_choices, current_choices())) { print('updating') updateSelectizeInput(session, 'words', choices = new_choices, selected = input$words, server = TRUE) current_choices(new_choices) # 更新存储的当前选项 } }, ignoreNULL = FALSE) } runGadget(shinyApp(ui, server), viewer = browserViewer()) } run_ui()
如果你的选项数据量不大,也可以尝试去掉server=TRUE,非server模式下的更新触发频率会低一些,但如果需要处理大量选项,上面的方案依然是最可靠的。
内容的提问来源于stack exchange,提问作者alexvpickering
相关产品推荐
相关产品推荐

