使用 >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
简短的回答是在您的更新中明确重新指定您的 choices
和 server
。
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")
})
}
updateSelectizeInput
中 server
的默认值为 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))
我有一个闪亮的应用程序,其中包含服务器端 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
简短的回答是在您的更新中明确重新指定您的 choices
和 server
。
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")
})
}
updateSelectizeInput
中 server
的默认值为 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))