当数字增加时,动态创建的观察者不再反应

时间:2019-09-23 16:24:10

标签: r shiny

我正在尝试为闪亮的应用程序实现保存文件系统。所有创建的书签都列在数据表中,并且可以通过单击书签名称来加载。我希望用户能够通过单击适当的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”文件夹。

我将不胜感激。谢谢。

0 个答案:

没有答案