r-在使用insertUI和Shiny模块时恢复已添加书签的Shiny应用程序



我正在尝试恢复一个应用程序的状态,该应用程序包括在Shiny模块内使用renderUI()生成的selectizeInput()。因为(在我的真实应用程序中(选择的数量很大,所以我使用服务器端选择——我认为这是主要的障碍。

为什么以下示例应用程序在进行选择、添加书签,然后复制并粘贴到新的浏览器选项卡后,不恢复ns("choices")输入的选择?

library(shiny)
choices <- c("a", "b", "c")
insert_choices_ui <- function(id) {
ns <- NS(id)
tags$div(
id = ns("main"),
selectInput(inputId = ns("select"), label = "Select", choices = c("no", "yes")),
uiOutput(ns("ui1"))
)
}
insert_choices_server <- function(id) {
moduleServer(
id,
function(input, output, session) {
ns <- session$ns

output$ui1 <- renderUI({
req(input$select)
if (input$select == "yes") {
tags$div(selectizeInput(
inputId = ns("choices"),
label = "Choices",
choices = NULL,
multiple = TRUE
))
}
})

observeEvent(input$select, ignoreNULL = FALSE, ignoreInit = FALSE,  {
updateSelectizeInput(
session,
inputId = "choices",
choices = choices,
server = TRUE
)
})
})
}
ui <- function(request) {
fluidPage(
id = "main",
actionButton("addButton", "Add Options"),
bookmarkButton()
)
}
server <- function(input, output, session) {
observeEvent(input$addButton, ignoreNULL = TRUE, ignoreInit = TRUE, {
insertUI(selector = "#main", ui = {
insert_choices_ui(paste0("id", input$addButton))
})
insert_choices_server(id  = paste0("id", input$addButton))
})

onRestore(function(state) {
for (i in seq_len(input$addButton)) {
insertUI("#main", ui = insert_choices_ui(id = paste0("id", i)))

insert_choices_server(id = paste0("id", i))
}
})

onRestored(function(state) {
if (!is.null(state$input$addButton) && state$input$addButton > 0) {
for (i in seq_len(input$addButton)) {
updateSelectizeInput(
session,
paste0("id", i, "-choices"),
choices = choices,
selected = state$input[[paste0("id", i, "-choices")]],
server = TRUE
)
}
}
})
}
enableBookmarking(store = "server")
shinyApp(ui, server)

这里的问题是,在onRestored设置值后,您对insert_choices_server的调用被触发,并且您正在运行代码的这一部分,它取消了您的书签所选择的内容:

observeEvent(input$select, ignoreNULL = FALSE, ignoreInit = FALSE,  {
updateSelectizeInput(
session,
inputId = "choices",
choices = choices,
server = TRUE
)
})

删除这些行并更改renderUI函数以传入选项:

output$ui1 <- renderUI({
req(input$select)
if (input$select == "yes") {
tags$div(selectizeInput(
inputId = ns("choices"),
label = "Choices",
choices = choices,
multiple = TRUE
))
}
})

(省略了代码的其余部分,因为它没有改变(

最新更新