我有一个使用模块的闪亮应用程序。在这个应用程序中,有几个下拉菜单需要在表格中填充选项。第一个下拉列表与第二个下拉列表相关,并提供行过滤器以更改表第二列中第二个下拉列表的值,但是第一个下拉列表中的值不应更改表第一列中的值。
该表应首先自动填充下拉列表的默认值(这些值各不相同,因此不能硬编码)。当应用程序的用户希望在表格中发生更改时,他们将查看选项并单击更新按钮。从这个可重现的例子中看不出来,但在更大的应用程序中,用户需要从他们上次更新的数据中不断更新表,而不仅仅是发送一个完整的数据表来重新填充整个数据。我知道如何使用下拉列表中的值来填充表格一次,但我无法理解如何将表格(或任何对象)存储在某处以便可以连续访问和更新。
如果描述不完全清楚,我希望在初始化时出现这样的表:
然后,如果我将下拉列表 2 更改为“b”并单击更新表,我希望它看起来像这样:
最后,如果我将下拉菜单 1 更改为“三明治”,然后将下拉菜单 2 更改为“a”并单击更新表,我希望该表如下所示:
下面是一个最小示例的代码,在TabButtonServer
模块中你会看到我最好的尝试让它工作,但它没有。如上所述,问题的症结是我不知道在更新表时应该如何存储表,以便以后可以再次引用它。我非常感谢有人可以提供的任何帮助。
## first drop down
ChooseUI1 <- function(id) {
selectInput(NS(id, "choice1"),
label=NULL,
choices=c("foo", "bar", "ham", "sandwich"))
}
ChooseServer1 <- function(id) {
moduleServer(id, function(input, output, session) {
reactive({
input$choice1
})
})
}
## second drop down
ChooseUI2 <- function(id) {
selectInput(NS(id, "choice2"),
label=NULL,
choices=c("a", "b", "c", "d"))
}
ChooseServer2 <- function(id) {
moduleServer(id, function(input, output, session) {
reactive({
input$choice2
})
})
}
## button to change table
TabButtonUi <- function(id){
actionButton(NS(id, "tab_change"),
label="Update Table")
}
TabButtonServer <- function(id, c1, c2) {
stopifnot(is.reactive(c1))
stopifnot(is.reactive(c2))
moduleServer(id, function(input, output, session) {
start_table <- reactive({
cbind.data.frame(col1=c("foo", "bar", "ham", "sandwich"),
col2=c("a", "b", "c", "d"),
stringsAsFactors=FALSE)
})
new_table <- data.frame(col1=character(), col2=character())
output_change <- eventReactive(input$tab_change, {
if(input$tab_change == 0) {
new_table <- start_table()
} else {
new_table[new_table[ , "col1"] == c1(), "col2"] <<- c2()
}
new_table
}, ignoreNULL=FALSE)
reactive({
output_change()
})
})
}
## view table
viewTabUi <- function(id){
tableOutput(NS(id, "view_tab"))
}
viewTabServer <- function(id, tab) {
stopifnot(is.reactive(tab))
moduleServer(id, function(input, output, session) {
output$view_tab <- renderTable(tab())
})
}
## the app
ui <- navbarPage(
title="test",
tabPanel(title="first page",
sidebarLayout(
sidebarPanel(
ChooseUI1("c1"),
ChooseUI2("c2"),
TabButtonUi("tab"),
viewTabUi("view_tab")
),
mainPanel(
)
)
)
)
server <- function(input, output, session) {
c1 <- ChooseServer1("c1")
c2 <- ChooseServer2("c2")
tab <- TabButtonServer("tab", c1, c2)
viewTabServer("view_tab", tab)
}
shinyApp(ui, server)