R DT的闪亮:如何读取/保留页面长度和列可见性

R DT的闪亮:如何读取/保留页面长度和列可见性,r,datatables,shiny,R,Datatables,Shiny,我对这个应用程序很陌生,所以如果它是显而易见的,请原谅我。我有一个可以基于地图中心重新计算的数据表。它很好用。但是,我希望阅读并保留某些设置:即页面长度和列可见性。此时,如果用户更改为每页20个条目并移动地图,则会使用colvis in按钮以默认页面长度和列vis重新呈现地图。我想我可以将它存储在某个变量中,并在重新呈现表时检索它,但不确定如何从选项内部读取。 它是建立在R工作室的光泽 有什么想法吗 编辑:我使用选项stateSave=TRUE获得了关于页面长度和列可见性的数据,然后读取输入$B

我对这个应用程序很陌生,所以如果它是显而易见的,请原谅我。我有一个可以基于地图中心重新计算的数据表。它很好用。但是,我希望阅读并保留某些设置:即页面长度和列可见性。此时,如果用户更改为每页20个条目并移动地图,则会使用colvis in按钮以默认页面长度和列vis重新呈现地图。我想我可以将它存储在某个变量中,并在重新呈现表时检索它,但不确定如何从选项内部读取。 它是建立在R工作室的光泽 有什么想法吗

编辑:我使用选项stateSave=TRUE获得了关于页面长度和列可见性的数据,然后读取输入$Btable_state$length,我也可以读取哪些列是可见的,但现在我的问题是:当重新呈现表时,它首先变为NULL值,覆盖输入$Btable_state中存储的任何内容。只有通过对过滤器的更改,而不是通过重新呈现表本身的活动,才能捕获并影响它

EDIT2:由于我的应用程序需要连接到我的google工作表,所以不可复制的内容可以在Github vnijs/dt_state的以下示例中尝试。如何在对列重新排序时保留非默认页面长度(例如50),但不将操作链接到selectizeInput,只保留最后一个正确状态

#ui.r
shinyUI(fluidPage(
  sidebarLayout(
    sidebarPanel(
      uiOutput("ui_view_vars"),
      tags$a(id = "refresh", href = "#", class = "action-button",
             list(icon("refresh"), "Clear state"),
             onclick = "window.location.reload();")
    ),
    mainPanel(
      tabPanel("View", DT::dataTableOutput("dataviewer")

      )
    )
  )
))

#server.r
library(shiny)
library(DT)

dat <- iris

## store state in global environment for now
if (!exists("r_state")) r_state <- list()

## Only used from a 'clean' start
r_state$dataviewer_search_columns <- list("","2.5...4","","","[\"setosa\"]")

shinyServer(function(input, output, session) {
  output$ui_view_vars <- renderUI({
    vars <- colnames(dat)

    ## using selectizeInput with drag_drop and DT
    selectizeInput("view_vars", "Select variables to show:", choices  = vars,
                   selected = vars, multiple = TRUE,
                   options = list(plugins = list('remove_button', 'drag_drop')))
  })

  ## make nested list
  mknl <- function(x) list(search = x)

  observeEvent(input$dataviewer_search_columns, {
    r_state$dataviewer_search_columns <<- input$dataviewer_search_columns
  })

  observeEvent(input$dataviewer_state, {
    r_state$dataviewer_state <<- input$dataviewer_state
  })

  observeEvent(input$refresh, {
    r_state <<- list()
  })

  output$dataviewer <- DT::renderDataTable({
    req(input$view_vars)

    search <- r_state$dataviewer_state$search$search
    if (is.null(search)) search <- ""

    DT::datatable(iris[,input$view_vars],
                  filter = list(position = "top", clear = TRUE),
                  rownames = FALSE,
                  selection = "none",
                  options = list(
                    stateSave = TRUE,
                    searchCols = lapply(r_state$dataviewer_search_columns, mknl),
                    search = list(search = search, regex = TRUE),
                    order = {if (is.null(r_state$dataviewer_state$order)) list()
                      else r_state$dataviewer_state$order},
                    processing = FALSE
                  ),
                  callback = DT::JS("$(window).unload(function() { table.state.clear(); })")
    )
  })

  output$tbl_col_search <- renderPrint(input$dataviewer_search_columns)

})

好的,看一下下面的例子,它应该保留您的分页。请注意,我添加了一个按钮,它可以从头开始将所有内容呈现为第一个值。请看一看示例和页面

rm(list=ls())
library(shiny)
library(DT)

ui <- basicPage(actionButton("Go","Go"),DT::dataTableOutput('x1'))

server <- shinyServer(function(input, output, session){

  tableparams <- reactiveValues()
  observeEvent(input$Go,{
    if(is.null(input$x1_rows_current)){
      tableparams$pageLength <- 5
    }
    else{
      tableparams$pageLength <- length(input$x1_rows_current)
    }
  })
  my_data <- eventReactive(input$Go,{iris})
  output$x1 = DT::renderDataTable(datatable(my_data(),options = list(pageLength = tableparams$pageLength)))
})
shinyApp(ui = ui, server = server)

我也有类似的需求,以下是我的发现:

要使用从当前行计算的方法自动监视页面长度值,需要一个反应式表达式而不是按钮。但是,这不起作用,因为当表刷新时,当前行将变为无效,这会阻止反应式表达式求值,它将简单地停止,您不能通过检查null跳过它

您原来的实际解决方案可以更好地工作,但我们需要更具体地观察页面长度的变化,而不是整个状态。observeEventinput$dataviewer\u state$length。您的问题为空,触发了该事件。也许它是在shiny中更新的,现在observeEvent在默认情况下不会触发NULL。请参阅observeEvent中有关ignoreNULL的帮助

当使用stateSave=TRUE时,它会将状态保存在html5本地存储中,该存储将在整个会话中保存,即使R全局环境为空,这也可能会让用户感到困惑。我使用stateDuration=-1来使用会话存储而不是本地存储


您有多少个表1?抱歉,应该提到两个表,它们在内容上没有关联,我只想保留一个表,但不介意它保留在两个表上。您希望两个表的每页数字相同吗?我想保留用户从列表中选择的任何内容,或者使用colvis按钮进行查看。非常感谢,列可见性属性的名称是什么?此外,该操作链接到按钮Go,如果我希望它是自动的,没有单击操作,我该如何做?该表可以通过以下方式重新呈现:更改缩放、更改平移、更改日期筛选器-有太多的操作要附加到该表。最后但并非最不重要的是-如果用户每页选择25个条目,但当前筛选视图只有21个条目,则所有下一个视图的页面长度都将为21,如果我的回答正确的话understanding@Slav你能提供一个最小的例子,这样我就可以重写我的,必须有一个反应式表达式,你正在使用的映射将触发表。我可能也可以调用表列,因为有一个属性。对于最后一点,您可以将其四舍五入到最接近的5,或者使用密封函数calls的顶部,或者在我想要粘贴时使用多个字符;,让我简化一下