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