我想在模块之间传递一个数据集(以下代表中的
iris
)。一旦通过,我想点击一个按钮来下载数据集。 我无法下载数据集。它是一个更大的应用程序的一部分,所以我想在 reprex 中尽可能保持一致。例如,我想继续使用 bs4Dash,但我也想保持文件结构不变。这也适用于 boxDropdown()
和 boxDropdownItem()
的使用。根据他们的 documentation here 如果我传递一个 id
参数,它将表现为一个 actionButton()
,因此我没有为 actionButton()
使用明确的 downloadHandler()
。在下面的 reprex 中,我添加了打印语句来跟踪和验证该过程。我曾尝试从模块服务器返回一个值(例如 seen here),但这没有用。所以我创建了这个代表来帮助调试它。
app/
├── global.R
├── server.R
├── ui.R
└── modules/
app/modules
├── first_module.R
└── second_module.R
要测试 reprex,请运行
global.R
。我正在尝试解决数据未下载的问题。
# Load necessary libraries
require(shiny)
require(bs4Dash)
# Source the modules
source(file = "modules/second_module.R", local = TRUE)
source(file = "modules/first_module.R", local = TRUE)
# Define the server for the Shiny app
## This isn't necessarily needed with the use of moduleServer()
## Included here in case the file is needed in the codebase
server <- function(input, output, session) {
# Call the second module's server with the iris dataset
secondModuleServer(id = "dataDownload", dataset = iris)
# Call the first module's server
firstModuleServer(id = "firstModule")
}
# Define the UI for the Shiny app
ui <- bs4DashPage(
header = bs4DashNavbar(),
sidebar = bs4DashSidebar(
sidebarMenu(
menuItem("First Module", tabName = "firstModule", icon = icon("home"))
)
),
controlbar = bs4DashControlbar(),
footer = bs4DashFooter(),
title = "Minimal Viable Shiny App",
body = bs4DashBody(
tabItems(
tabItem(
tabName = "firstModule",
firstModuleUI(id = "firstModule", tabName = "firstModuleTab")
)
)
)
)
#' A Shiny Module: Pass downloadable dataset to another module
#' @title Modularized Downloading
#' @description This module will pass iris to the other module where it should download
# Source the second module
source("modules/second_module.R", local = TRUE)
# Define the first module's UI
firstModuleUI <- function(id, tabName) {
ns <- NS(id)
tabItem(tabName = tabName,
tabPanel("First Module",
box(title = "Reprex: Modularized Download",
dropdownMenu = secondModuleUI(id = ns("dataDownload"))
)
)
)
}
# Define the first module's server
firstModuleServer <- function(id) {
moduleServer(id, function(input, output, session) {
# Pass the iris dataset to the second module's server
secondModuleServer(id = "dataDownload", dataset = iris)
})
}
# A Shiny Module - To Download/Export Data In Different File Types
#' @title Download/Export User Updated Data
#' @description Users can download/export data as CSV
# Define the second module's UI
secondModuleUI <- function(id) {
ns <- NS(id)
boxDropdown(
boxDropdownItem("CSV", id = ns("csvdownload"), icon = icon("file-csv")),
icon = icon("download")
)
}
secondModuleServer <- function(id, dataset) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
print(head(dataset)) # check if the data being received
# Trigger the downloadHandler when the download_button is clicked
observeEvent(input$csvdownload, {
print("debug: button works")
output$csvdownload <- downloadHandler(
filename = function() {
paste("iris.csv", sep = "")
},
content = function(file) {
write.csv(dataset, file, row.names = FALSE)
print("debug: download processed")
}
)
})
})
}
感谢您的帮助。
也许你正在寻找这个(其余代码没有变化)。
# Define the second module's UI
secondModuleUI <- function(id) {
ns <- NS(id)
boxDropdown(
boxDropdownItem("", uiOutput(ns("csvdownload")) ),
icon = icon("download")
)
}
secondModuleServer <- function(id, dataset) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
print(head(dataset)) # check if the data being received
# Trigger the downloadHandler when the download_button is clicked
observeEvent(input$csvdownload, {
print("debug: button works")
})
output$csvdownload <- renderUI({
downloadBttn(ns("saveCSV"),
HTML("CSV"),
style = "fill",
color = "default",
size = "md",
block = TRUE,
no_outline = TRUE
)
})
output$saveCSV <- downloadHandler(
filename = function() {
paste("iris.csv", sep = "")
},
content = function(file) {
write.csv(dataset, file, row.names = FALSE)
print("debug: download processed")
}
)
})
}
# Define the UI for the Shiny app
ui <- bs4DashPage(
header = bs4DashNavbar(),
sidebar = bs4DashSidebar(
sidebarMenu(
menuItem("First Module", tabName = "firstModule", icon = icon("home"))
)
),
controlbar = bs4DashControlbar(),
footer = bs4DashFooter(),
title = "Minimal Viable Shiny App",
body = bs4DashBody(
tabItems(
tabItem(
tabName = "firstModule",
firstModuleUI(id = "firstModule", tabName = "firstModuleTab")
)
)
)
)
# Define the server for the Shiny app
## This isn't necessarily needed with the use of moduleServer()
## Included here in case the file is needed in the codebase
server <- function(input, output, session) {
# Call the second module's server with the iris dataset
#secondModuleServer(id = "dataDownload", dataset = iris)
# Call the first module's server
firstModuleServer(id = "firstModule")
}