【问题标题】:Edited DataTable is not updating in Shiny Module已编辑的 DataTable 未在 Shiny 模块中更新
【发布时间】:2018-11-03 22:32:14
【问题描述】:

我想在数据表中嵌入 numericInput 和 checkBoxInput。我有一个 Xie Yihui 的例子,效果很好。和我想要的完全一样。 但是当代码被包装在一个模块中时,编辑后的表不会更新。我读到这可能是由于命名空间,但我不知道如何解决它。

这里是要点:

Gist: edit DataTable in Shiny App

Gist: edit DataTable in Shiny Module

提前致谢:)

【问题讨论】:

    标签: datatable module shiny


    【解决方案1】:

    只有一个小修复,如果您不熟悉 Shiny 模块,当然很难看出这一点。您在 Module Server 函数中创建的每个 Input ID 都必须包含在 ns 中(就像您在 UI 中所做的那样),但该函数隐藏在服务器函数中的 session$ns 中。因此,在创建输入的第 18 行中,必须使用 session$ns 调整其 ID。来自

    inputs[i] = as.character(FUN(paste0(id, i), label = NULL, ...))
    

    inputs[i] = as.character(FUN(paste0(session$ns(id), i), label = NULL, ...))
    

    完整代码:

    library(shiny)
    library(DT)
    
    
    editTableUI <- function(id) {
      ns <- NS(id)
      tagList(
        DT::dataTableOutput(ns('x1')),
        verbatimTextOutput(ns('x2'))
      )
    }
    
    editTable <- function(input, output, session) {
      # create a character vector of shiny inputs
      shinyInput = function(FUN, len, id, ...) {
        inputs = character(len)
        for (i in seq_len(len)) {
          inputs[i] = as.character(FUN(paste0(session$ns(id), i), label = NULL, ...))
        }
        inputs
      }
    
    
    
      # obtain the values of inputs
      shinyValue = function(id, len) {
        unlist(lapply(seq_len(len), function(i) {
          value = input[[paste0(id, i)]]
          if (is.null(value)) NA else value
        }))
      }
    
      # a sample data frame
      res = data.frame(
        v1 = shinyInput(numericInput, 100, 'v1_', value = 0),
        v2 = shinyInput(checkboxInput, 100, 'v2_', value = TRUE),
        v3 = rnorm(100),
        v4 = sample(LETTERS, 100, TRUE),
        stringsAsFactors = FALSE
      )
    
      # render the table containing shiny inputs
      output$x1 = DT::renderDataTable(
        res, server = FALSE, escape = FALSE, options = list(
          preDrawCallback = JS('function() {
                               Shiny.unbindAll(this.api().table().node()); }'),
          drawCallback = JS('function() {
                            Shiny.bindAll(this.api().table().node()); } ')
          )
          )
      # print the values of inputs
      output$x2 = renderPrint({
        data.frame(v1 = shinyValue('v1_', 100), v2 = shinyValue('v2_', 100))
      })
          }
    
    shinyApp(
      ui = fluidPage(
        editTableUI("test")
      ),
    
      server = function(input, output) {
        callModule(editTable, "test")
      }
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-08
      • 2020-09-14
      • 1970-01-01
      • 1970-01-01
      • 2021-05-06
      • 1970-01-01
      • 2018-10-02
      相关资源
      最近更新 更多