我正在尝试为闪亮的应用程序实现保存文件系统。所有创建的书签都列在数据表中,并且可以通过单击书签名称来加载。我希望用户能够通过单击适当的actionLink来删除文件。 我的代码适用于已经存在的书签,但是一旦我添加了另一个书签,除了最后添加的actionLink,其他代码似乎都无法正常工作。
我修改了Michal Majka的代码,他为类似的问题(Generate observers for dynamic number of inputs)给出了很好的答案。我的代码本质上是相同的,但是我无法发现出了什么问题。该应用在运行时不会产生任何错误。
library(shiny)
library(magrittr)
library(tibble)
ui <- function(request) {
fluidPage(
sidebarLayout(
sidebarPanel(
# example input UI
numericInput("num", "No.1", 0),
textInput("text", "Default"),
checkboxInput("check", "Choose"),
actionButton("debug", "Debug")
),
mainPanel(
wellPanel(
# saved bookmarks
DT::DTOutput("savesTbl"),
splitLayout(
textInput("sessionName", NULL, placeholder = "Insert name ..."),
bookmarkButton("Save")
),
verbatimTextOutput("status", placeholder = TRUE)
)
)
)
)
}
server <- function(input, output, session) {
observeEvent(input$debug, browser())
if (file.exists("shiny_bookmarks/saves.csv")) {
saves_tbl <- reactiveVal({ read.csv("shiny_bookmarks/saves.csv") })
} else {
saves_tbl <- reactiveVal({ as.data.frame(matrix(ncol = 4, nrow = 0, dimnames = list(NULL, c("Name", "Time", "User", "Version")))) })
}
# later to be included in a modal panel / module ----
vals <- reactiveValues(links = NULL, observer = NULL, IDs = NULL)
output$savesTbl <- DT::renderDT({
if (nrow(saves_tbl()) > 0) {
IDs <- seq_len(nrow(saves_tbl()))
# For the first time the table is created, create links & observers and save the
# sequence of integers which gives unique identifiers of created observers
if (is.null(vals$IDs)) {
vals$links <- lapply(IDs, function(x) { as.character(actionLink(paste0("deleteLink", x), label = "Delete")) })
vals$observer <- lapply(IDs, function(x) { observeEvent(input[[paste0("deleteLink", x)]], { print(x) }) })
vals$IDs <- IDs
# Whenever the table gets updated, create links & observers that are not defined yet
} else if (!all(IDs %in% vals$IDs)) {
new_ind <- !(IDs %in% vals$IDs)
vals$links <- append(vals$links,
lapply(IDs[new_ind], function(x) { as.character(actionLink(paste0("deleteLink", x), label = "Delete")) }))
vals$observer <- append(vals$observer,
lapply(IDs[new_ind], function(x) { observeEvent(input[[paste0("deleteLink", x)]], {
print(x)
# save_state_id <- sub(".*=(.*)\".*", "\\1", saves_tbl()[[x, 1]])
# save_file_path <- paste0("shiny_bookmarks/", save_state_id)
# unlink(save_file_path, recursive = TRUE)
# saves_tbl()[-x,] %>%
# saves_tbl()
}) }))
vals$IDs <- IDs
}
table <- DT::datatable(add_column(saves_tbl(), "Delete" = vals$links),
escape = FALSE,
options = list(
preDrawCallback = DT::JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback = DT::JS('function() { Shiny.bindAll(this.api().table().node()); }')))
return(table)
} else {
return(saves_tbl())
}
})
# for debug purposes
output$status <- renderText({ paste("Saves:", nrow(saves_tbl()), "\n", "Links:", length(vals$links), "\n", "Observer:", length(vals$observer)) })
# save
setBookmarkExclude(c("bookmarkBtn", "sessionName", "savesTbl_cell_clicked", "savesTbl_rows_all", "savesTbl_rows_current",
"savesTbl_rows_selected", "savesTbl_search", "savesTbl_state", "savesTbl_row_last_clicked")
)
onBookmarked(function(url) {
add_row(saves_tbl(),
Name = as.character(a(input$sessionName, href = url)),
Time = as.character(Sys.time()),
User = Sys.getenv("USERNAME"),
Version = "0.0.0.9000") %>%
saves_tbl()
})
session$onSessionEnded(function() {
write.csv(isolate(saves_tbl()), "shiny_bookmarks/saves.csv", row.names = FALSE)
})
}
enableBookmarking("server")
shinyApp(ui, server)
现在,我希望每次单击“删除” -actionLink都可以打印其ID号(例如,单击“ deleteLink1”将显示“ 1”)。请注意,单击“保存”按钮会在您的工作目录中生成一个“ shiny_bookmarks”文件夹。
我将不胜感激。谢谢。