使用 >1000 个选项更新服务器端选择输入的选择失败

Updating selection of server-side selectize input with >1000 choices fails

我有一个闪亮的应用程序,其中包含服务器端 selectize 输入和一长串(>10k)的选择。 我想在单击按钮时更新 selection。这是一个可重现的例子

library(shiny)

ui <- fluidPage(
  actionButton('buttonid','Button'),

  selectizeInput("listid", "A long list", choices = NULL)
  )

server <- function(input, output, session) 
  {
  updateSelectizeInput(session, "listid", choices = paste("Item", 1:10000), server = T)
  observeEvent(input$buttonid,
               {
               updateSelectizeInput(session, "listid", selected = "Item 1234")
               })
  }

shinyApp(ui = ui, server = server)

当我按下按钮时,上面的代码导致空白 selection。 但是,如果我搜索 "Item 1234",然后更改 selection,然后按下按钮,现在该项目得到 selected.

此外,尝试 select 项目 1 和 1000 之间的项目不会出现问题,大概是因为一开始加载了 1000 个项目。

这似乎类似于这个老错误,但我不确定是否有解决方法https://github.com/rstudio/shiny/issues/1018

简短的回答是在您的更新中明确重新指定您的 choicesserver

server <- function(input, output, session) 
{

  myChoices <- paste("Item", 1:10000)

  updateSelectizeInput(session, "listid", choices = myChoices, server = T)
  observeEvent(input$buttonid,
               {
                 updateSelectizeInput(session, "listid",
                                      server = TRUE,
                                      choices = myChoices,
                                      selected = "Item 1234")

               })
}

updateSelectizeInputserver 的默认值为 FALSE。这会导致代码放入使用 updateSelectInput 的控制语句中。来自函数代码

function (session, inputId, label = NULL, choices = NULL, selected = NULL, 
    options = list(), server = FALSE) 
{
    ...

    if (!server) {
        return(updateSelectInput(session, inputId, label, choices, 
            selected))
    }

   ...

假设所有选项都存在(但正如您提到的,只有前 1000 个选项存在),这会向客户端发送一条消息。

仅设置 server = TRUE 会导致单击按钮时出错。

Warning: Error in [.data.frame: undefined columns selected
  [No stack trace available]

我没有完全追查原因,但它最终创建了一个空选择 data.frame,其属性表示 selected 值。我猜测在对 session 对象的函数调用中的其他地方,此属性正用于尝试 select 从空 data.frame 创建的列。

更新功能似乎没有更改存储在服务器上的 choices,所以这大概就是为什么当您搜索它时它就在那里。在更改 selected 值期间,它似乎试图从 NULL 选择列表而不是服务器上的选择列表中 select。

当使用超出初始列表的 selected 值进行更新时,您似乎必须重新创建 selectizeInput

您可以使用 maxOptions 来呈现所有值,根据您选择的大小可能就足够了:

selectizeInput("listid", "A long list", choices = NULL, options = list(maxOptions = 10000))