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

nic*_*ico 3 r shiny selectize.js

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

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)
Run Code Online (Sandbox Code Playgroud)

当我按下按钮时,上面的代码会导致一个空白的选择。但是,如果我搜索“Item 1234”,然后更改选择并按下按钮,现在该项目被选中。

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

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

Mar*_*cus 5

简短的回答是在您的更新中明确重新指定您的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")

               })
}

Run Code Online (Sandbox Code Playgroud)

serverin的默认值updateSelectizeInputFALSE。这会导致代码进入一个使用的控制语句updateSelectInput。从功能代码

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

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

   ...
Run Code Online (Sandbox Code Playgroud)

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

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

Warning: Error in [.data.frame: undefined columns selected
  [No stack trace available]
Run Code Online (Sandbox Code Playgroud)

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

更新功能似乎不会更改choices存储在服务器上的内容,所以这大概就是您搜索它时它在那里的原因。在更改选定值期间,它似乎试图从 NULL 选项列表而不是服务器上的选项列表中进行选择。

似乎您基本上必须selectizeInput在使用初始列表之外的选定值进行更新时重新创建您的。


Cle*_*ang 5

您可以使用 maxOptions 来呈现所有值,这可能就足够了,具体取决于您选择的大小:

selectizeInput("listid", "A long list", choices = NULL, options = list(maxOptions = 10000))
Run Code Online (Sandbox Code Playgroud)