css 如何将自定义头插入到使用DT Shiny呈现的表中,并使用来自单独模块的代码?

mpgws1up  于 2023-06-07  发布在  其他
关注(0)|答案(1)|浏览(148)

我对使用名称空间在R Shiny中进行模块化是完全陌生的,我觉得它不是很直观。在下面的代码中,分为“核心应用代码”和“模块代码”,React对象iris1在核心应用代码和模块代码之间传输,用于模块代码中的几个函数。代码在调用模块服务器函数(及其定义)时使用参数。它将从一个模块返回的值赋给主服务器函数中的reactive,然后通过调用其服务器函数将该reactive传递给第二个模块。
下面的代码似乎可以工作,除了客户头(在模块代码中的myContainer函数中以CSS呈现的第二个头),它跨越几列,出现在DT表头上方)不工作。我在下面做错了什么?

编码应用编码:

library(shiny)
library(DT)

source("C:/Users/.../my_module.R") 

ui <- fluidPage(
  numericInput("number", label = "Enter sepal length multiplier:", value = 1),
  DTOutput('tbl')
)

server <- function(input, output) {
  iris1 <- reactive({
    tmp <- iris
    tmp$Sepal.Length <- tmp$Sepal.Length * input$number
    tmp
  })
  
  output$tbl <- renderDT({renderTable(iris1())})
  
  # Pass the reactive object iris1 to the module server function
  callModule(my_module_server, "myModule", iris1 = iris1)
}

shinyApp(ui, server)

模块编码(另存为 my_module.R):

myContainer <- function() {
  htmltools::withTags(table(
    class = 'display',
    thead(
      tr(
        th(style = "border-top: none;border-bottom: none;"),
        th(colspan = 4, 'Lengths and widths',
           class = "dt-center",
           style = "border-right: solid 0.5px;border-left: solid 0.5px;border-top: solid 0.5px; background-color:#E6E6E6;"
        )
      ),
      tr(
        th(),
        lapply(names(iris1()), th)  # Access iris1 reactive object
      )
    )
  ))
}

renderTable <- function(data) {
  datatable(
    data,
    container = myContainer(),
    options = list(lengthChange = FALSE)
  )
}

my_module_ui <- function(id) {
  ns <- NS(id)
  DTOutput(ns("tbl"))
}

my_module_server <- function(input, output, session, iris1) {
  output$tbl <- renderDT({
    renderTable(
      iris1()  # Access iris1 reactive object
    )
  })
}
icnyk63a

icnyk63a1#

下面是一个模块化代码的工作示例。当你在代码中添加了一个模块时,你实际上并没有使用它。您的tbl输出是在主服务器中创建的,并且只有此输出包含在主UI中。
相反,我将模块UI添加到主UI,并从主服务器删除output$tbl以及相应的渲染函数。此外,由于myContainer只是一个函数,因此可以通过将表的名称作为参数传递来使其自包含,而不是依赖于在应用程序的不同部分定义的reactive。实际上,当我运行你的代码时,我得到了一个错误,因为这个。另外,我看不出有任何理由用自定义函数覆盖shiny::renderTable。如果需要自定义函数,我建议使用不同的名称来明确这一点。最后,我切换到使用moduleServer而不是使用callModule的新样式模块。

library(shiny)
library(DT)

myContainer <- function(x) {
  htmltools::withTags(table(
    class = "display",
    thead(
      tr(
        th(style = "border-top: none;border-bottom: none;"),
        th(
          colspan = 4, "Lengths and widths",
          class = "dt-center",
          style = "border-right: solid 0.5px;border-left: solid 0.5px;border-top: solid 0.5px; background-color:#E6E6E6;"
        )
      ),
      tr(
        th(),
        lapply(x, th)
      )
    )
  ))
}

my_module_ui <- function(id) {
  ns <- NS(id)
  DTOutput(ns("tbl"))
}

my_module_server <- function(id, iris1) {
  moduleServer(id, function(input, output, session) {
    output$tbl <- renderDT({
      datatable(
        iris1(),
        container = myContainer(names(iris1())),
        options = list(lengthChange = FALSE)
      )
    })
  })
}

ui <- fluidPage(
  numericInput("number", label = "Enter sepal length multiplier:", value = 1),
  my_module_ui("myModule")
)

server <- function(input, output) {
  iris1 <- reactive({
    tmp <- iris
    tmp$Sepal.Length <- tmp$Sepal.Length * input$number
    tmp
  })

  my_module_server("myModule", iris1 = iris1)
}

shinyApp(ui, server)
#> 
#> Listening on http://127.0.0.1:3641

相关问题