【问题标题】:how to display dynamic tabPanels with DT inside multiple nested modules如何在多个嵌套模块中显示带有 DT 的动态 tabPanel
【发布时间】:2021-05-26 16:11:00
【问题描述】:

我真的需要以下代码的帮助,我使用 2 个嵌套模块在某些列的多个 tabPanelstabsetPanel 内)中显示 sampledata,但表格没有显示,我找不到里面的任何错误还没有。

PS:这只是一个可重现的例子,sampledata是用户在真实场景中上传的

library(shiny)
library(shinydashboard)
library(DT)

ui <- function() {
  dashboardPage(
    dashboardHeader(title = "abc"),
    dashboardSidebar(uiOutput("sidebarpanel")), 
    dashboardBody(uiOutput("body")))
}

server <- function(input, output, session) {
  output$sidebarpanel <- renderUI({
    tags$div(
      sidebarMenu(id = "tabs",
                  menuItem("Data", tabName = "data"))
    )
  })
  
  output$body <- renderUI({ 
    tabItems(ui_data1("data1", tabName = "data"))
  })
  
  input_data1 <- new.env()
  input_data1$a <- reactive(1)
  input_data1$b <- reactive(2)
  
  input_data2 <- server_data1("data1", input_data1)
}

ui_data1 <- function(id, tabName){ 
  ns <- NS(id)
  tabItem(tabName = tabName,
          uiOutput(ns("body")))
}

server_data1 <- function(id, input_data1) {
  ns <- NS(id)
  moduleServer(id, function(input, output, session) {
    output$body <- renderUI({
      tabsetPanel(
        ui_data2(ns("info1"), "Info1")
      )
    })
    
    data2 <- new.env()
    data2$input_data2 <- server_data2("info1", input_data1)
    
    return(data2)
  })
}

ui_data2 <- function(id, title) {
  ns <- NS(id)
  tabPanel(title = title,
           uiOutput(ns("body")))
}

server_data2 <- function(id, input_data1) {
  ns <- NS(id)
  moduleServer(id, function(input, output, session) {
    c <- eventReactive(input_data1$a(), {
      2
    })
    
    sampledata <- reactive(mtcars)
    
    output$body <- renderUI({
      all_cyl <- unique(sampledata()$cyl)
      tbl_by_cyl <- lapply(seq_along(all_cyl), function(i) {
        tabPanel(all_cyl[i],
                     column(12, br(),
                            box(width = "auto",
                                DT::dataTableOutput(ns(paste0("cyl", i)), 
                                                    width = "100%"))))
      })
      do.call(tabsetPanel, tbl_by_cyl)
    })
    
    observe({
      sampledata <- sampledata()
      all_cyl <- unique(sampledata$cyl)
      
      lapply(seq_along(all_cyl), function(i) {
        output[[paste0("cyl", i)]] <- DT::renderDataTable({
          datatable(sampledata[sampledata$cyl == all_cyl[i], ])
        })
      })
    })
    
    return(sampledata)
  })
}

shinyApp(ui, server)

输出: output of above code

【问题讨论】:

    标签: r shiny shinydashboard dt shiny-reactivity


    【解决方案1】:

    你们很亲密。你只需要在server_data1server_data2 中的ns &lt;- session$ns。试试这个

      library(shiny)
      library(shinydashboard)
      library(DT)
      
      ui <- function() {
        dashboardPage(
          dashboardHeader(title = "abc"),
          dashboardSidebar(uiOutput("sidebarpanel")), 
          dashboardBody(uiOutput("body")))
      }
      
      server <- function(input, output, session) {
        output$sidebarpanel <- renderUI({
          tags$div(
            sidebarMenu(id = "tabs",
                        menuItem("Data", tabName = "data"))
          )
        })
        
        output$body <- renderUI({ 
          tabItems(ui_data1("data1", tabName = "data"))
        })
        
        input_data1 <- new.env()
        input_data1$a <- reactive(1)
        input_data1$b <- reactive(2)
        
        input_data2 <- server_data1("data1", input_data1)
      }
      
      ui_data1 <- function(id, tabName){ 
        ns <- NS(id)
        tabItem(tabName = tabName,
                uiOutput(ns("body1")))
      }
      
      server_data1 <- function(id, input_data1) {
        #ns <- NS(id)
        moduleServer(id, function(input, output, session) {
          ns <- session$ns
          output$body1 <- renderUI({
            tabsetPanel(
              ui_data2(ns("info1"), "Info1")
            )
          })
          
          data2 <- new.env()
          data2$input_data2 <- server_data2("info1", input_data1)
          
          return(data2)
        })
      }
      
      ui_data2 <- function(id, title) {
        ns <- NS(id)
        tabPanel(title = title,
                 uiOutput(ns("body2")))
      }
      
      server_data2 <- function(id, input_data1) {
        #ns <- NS(id)
        moduleServer(id, function(input, output, session) {
          ns <- session$ns
          c <- eventReactive(input_data1$a(), {
            2
          })
          
          sampledata <- reactive(mtcars)
          
          output$body2 <- renderUI({
            all_cyl <- unique(sampledata()$cyl)
            tbl_by_cyl <- lapply(seq_along(all_cyl), function(i) {
              tabPanel(all_cyl[i],
                       fluidRow(column(12, br(),
                              shinydashboard::box( width = "auto",
                                  DTOutput(ns(paste0("cyl", i)),width = "100%")))))
            })
            do.call(tabsetPanel, tbl_by_cyl)
          })
          
          observe({
            sampledata <- sampledata()
            all_cyl <- unique(sampledata$cyl)
            
            lapply(seq_along(all_cyl), function(i) {
              output[[paste0("cyl", i)]] <- renderDT({
                datatable(sampledata[sampledata$cyl == all_cyl[i], ])
              })
            })
          })
          
          return(sampledata)
        })
      }
      
      shinyApp(ui, server)
    

    【讨论】:

    • 哇,谢谢你的回答!但我不明白moduleServer 之前的ns &lt;- NS(id)moduleServer 内部的ns &lt;- session$ns 之间有什么区别?
    • session$nsns &lt;- NS(id) 的服务器端版本
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 2018-02-03
    • 2019-10-20
    • 2019-04-30
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    相关资源
    最近更新 更多