【发布时间】:2021-01-14 21:58:21
【问题描述】:
我正在尝试模块化一个闪亮的应用程序。到目前为止,它运行得很顺利,但是我在设计具有两个模块 A 和 B 的系统时遇到了麻烦,其中 A 需要来自 B 的数据,而 B 需要来自 A 的数据。
首先,按照this tutorial(闪亮版本 1.5),我得到了这个非常基本的自包含示例。
library(shiny)
#######################
# FILE MODULE #
# Load and save value #
#######################
fileModuleUI <- function(id) {
ns <- NS(id)
tagList(
fileInput(ns("fileInput"), "Input"),
downloadButton(ns("fileOutput"), "Save problem")
)
}
fileModuleServer <- function(id, textFieldData) {
moduleServer(
id,
function(input, output, session) {
# Write observer
output$fileOutput <- downloadHandler(
filename = function() { "myfile.dcf" },
content = function(file) { dput(textFieldData(), file) }
)
# Read observers
userFile <- reactive({
validate(need(input$fileInput, message = FALSE))
input$fileInput
})
fileContent <- reactive({
dget(userFile()$datapath)
})
return(fileContent)
}
)
}
###############
# MAIN UI #
###############
ui <- fluidPage(
sidebarLayout(
sidebarPanel(fileModuleUI("dataHandler")),
mainPanel(textInput("mainData", label = "Type your data in here"))
)
)
server <- function(input, output, session) {
fileContent <- fileModuleServer("dataHandler", reactive(input$mainData))
observe({
updateTextInput(session, "mainData", value = fileContent())
})
}
shinyApp(ui = ui, server = server)
使用这个漂亮的工具,我可以从textInput 中加载一行文本并将其保存在一个文件中。
现在我还想模块化我的mainPanel 中的内容。我们就叫它mainModule吧。
虽然构建mainModuleUI 很简单,但mainModuleServer 引入了一些交叉依赖问题:
-
fileModuleServer需要知道mainModuleServer的文本字段,以便将其值保存在文件中 -
mainModuleServer需要知道来自fileModuleServer的文件内容,以便在加载文件时更新其文本输入字段
因此,服务器可能看起来像这样:
fileModuleServer <- function(id, textFieldData) { ... }
mainModuleServer <- function(id, fileContent) { ... }
server <- function(input, output, session) {
# what to pass as second parameter?
fileContent <- fileModuleServer("dataHandler", ???)
# would passing fileContent even work?
mainModuleServer("mainPanel", fileContent)
}
有什么好的方法可以解决这个问题?
【问题讨论】: