【问题标题】:Shiny and DT: how to reset an output that depends on calculations over inputs?Shiny 和 DT:如何重置依赖于输入计算的输出?
【发布时间】:2020-11-27 03:50:59
【问题描述】:

我真的很难找到这个问题的标题,希望它有所帮助。

我有一个相当复杂的应用程序,在actionButton(本例中为“确认”)触发重新评估提供反应表的reactiveValues 数字后,我无法重置输出。

这导致selected 表只呈现一次,并且无论提供它的表更改多少次,它始终显示与第一次呈现相同的结果。

从这个例子中你会很容易明白我的意思。相信我,这是我来自的那个的极小值:

library(shiny)
library(DT)
 

ui <- fluidPage(
  DTOutput("table"),
  actionButton("checkvalues", "Check")
  
)

server <- function(input, output, session) {
  
  primedata <- reactiveValues(data = NULL)
  primedata$data <- as.numeric(Sys.time()) %% 10000 
  
  tabledata <- reactive({
    
    data <- data.frame(rep(primedata$data, 5))
    for (i in 1:5) {
      data$V1[i] <- as.character(selectInput(paste0("sel", i), "",
                                             choices = c("None selected" = 0,
                                                          "Icecream", "Donut"), 
                                                          selected = 0, width = "120px"))
  }
    return(data)
    })
  
  
  output$table <- renderDataTable( #Generar tabla
    
    tabledata(), filter = 'top', escape = FALSE, selection = 'none', server = FALSE,
    callback = JS("table.rows().every(function(i, tab, row) {
            var $this = $(this.node());
            $this.attr('id', this.data()[0]);
            $this.addClass('shiny-input-container');
          });
          Shiny.unbindAll(table.table().node());
          Shiny.bindAll(table.table().node());")
    
  )
  
  # helper function for reading inputs in DT
  shinyValue = function(id, len) { 
    unlist(lapply(seq_len(len), function(i) { 
      value = input[[paste0(id, i)]] 
      if (is.null(value)) NA else value 
    })) 
  }
  
  observeEvent(input$checkvalues, {
    
    datos <- tabledata()
    
      selected <- cbind(datos, data.frame(N = shinyValue("sel", nrow(datos)))) 
      selected <- selected %>% group_by(N) %>% summarise("see" = n())
    showModal(modalDialog(
      title = HTML('<h3 style="text-align:center;">Problem: this table will keep showing the same results as the first one presented</h3>'),
      renderDT(datatable(selected, options = list(dom = 't', ordering = F))),
      footer = actionButton("Confirm", "Confirm")))
    
  })
  
  observeEvent(input$Confirm, {
    
     primedata$data <- as.numeric(Sys.time()) %% 10000
      
     removeModal() 

    })
  
}

shinyApp(ui, server)

【问题讨论】:

  • 我不明白你的问题(我没有尝试过你的代码)但是要使用shinyjs,你必须在用户界面中包含useShinyjs()
  • 感谢您的意见。我删除了 ~shinyjs 的元素,因为这些元素不是问题的附带因素。
  • 所以你想得到一个包含选择的表格?对吧?
  • 是的,尽可能使用相同的依赖结构!

标签: r shiny datatable reactive


【解决方案1】:

当您更改primedata$data(通过单击“确认”按钮)时,这会重新呈现表格,并且您必须在此之前取消绑定:

ui <- fluidPage(
  tags$head(tags$script(
    HTML(
      "Shiny.addCustomMessageHandler('unbindDT', function(id) {
        var $table = $('#'+id).find('table');
        if($table.length > 0){
          Shiny.unbindAll($table.DataTable().table().node());
        }
      })")
  )),
  DTOutput("table"),
  actionButton("checkvalues", "Check")
)


  observeEvent(input$Confirm, {
    
    session$sendCustomMessage("unbindDT", "table")
    
    primedata$data <- as.numeric(Sys.time()) %% 10000
    
    removeModal() 
    
  })

【讨论】:

  • 我正在尝试使用您的解决方案,但在这种情况下,我的示例中输出的“表”名称可能不是最好的(我的应用程序中的数据表输出有另一个名称)。我不知道 javascript,所以...您的答案中 HTML 脚本上的所有 tables 是否都与输出有关,或者我应该保留其中的任何一个吗?
  • @DavidJorquera "table" in session$sendCustomMessage("unbindDT", "table") 指的是输出 id (output$table &lt;- renderDT(......))。
  • ...脚本保持不变,明白了...它适用于示例和我的应用程序。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
  • 2015-09-21
  • 2023-01-07
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
  • 2016-08-28
相关资源
最近更新 更多