我目前正在尝试使用Appsilon Rhino框架和shiny.fluent UI包建立一个模块化的Shiny应用程序。我试图在用户选择的输入之间获得一些React,以馈送到应用程序中的第二个窗格中,以显示下拉列表的选择,而无需用户返回下拉列表来查看他们选择了什么。数据模块(用户输入)馈送选择模块(显示选择),选择模块馈送到布局模块,布局模块基本上用于格式化和UI布局,布局模块馈送主.R文件,馈送app.R文件。
我已经尝试了几种不同的方法,通过定义特定的React元素并使用observe()和observeEvent(),但似乎无法解决基于用户更改显示的选择。这些将需要不断监测,因为用户可以进行一次选择,然后在同一会话中选择不同的一组列以获得不同的结果。下面各个模块的代码。
---data.R---
box::use(
shiny.fluent[Dropdown.shinyInput, Separator, updateDropdown.shinyInput],
shiny[moduleServer, NS, div, textOutput],
janitor[make_clean_names],
magrittr[`%>%`],
dplyr[mutate]
)
column_options <- c('column 1', 'column 2', 'column 3')
#' @export
ui <- function(id) {
ns <- NS(id)
div(
Separator('fields'),
Dropdown.shinyInput(
ns('cols'),
multiSelect = TRUE,
value = 'Please select columns to return',
options = column_options
))
}
#' @export
server <- function(id) {
moduleServer(id, function(input, output, session) {
cols_selected <- reactive({
input$cols})
list(
cols_selected = cols_selected
)
})
}
字符串
---selection.R---
box::use(
shiny.fluent[GroupedList, DetailsList, Text, Separator],
shiny[moduleServer, NS, div, textOutput],
htmlwidgets[JS],
DBI[dbGetInfo]
)
box::use(
app/view/data
)
col_headers <- list(
list(key = 'fields', fieldName = 'fields', name = 'Fields')
)
#' @export
ui <- function(id, cols_selected, fils_selected) {
ns <- NS(id)
div(
Separator('selected fields'),
DetailsList(items = cols_selected(), columns = col_headers)
)
}
#' @export
server <- function(id) {
moduleServer(id, function(input, output, session) {
cols_selected <- data$server('data', cols_selected)
})
}
型
---layout.R---
box::use(
shiny[...],
shiny.fluent[Stack, fluentPage, Text, Image],
glue[glue]
)
box::use(
app/view/selection,
app/view/data
)
## header UI details ----
header <- tagList(
div(
class = "page-title",
span('App', class = "title"),
br(),
span('data', class = "subtitle")
)
)
## selection pane UI details ----
selection <- selection$ui('selection', cols_selected)
## data pane UI details ----
data <- data$ui('data')
## helper functions ----
# function to create and style overall page
makePage <- function (contents) {
tagList(
contents
)
}
# function to create and style individual cards
makeCard <- function(title, content, size = 12, style = "") {
div(
class = glue("card ms-depth-8 ms-sm{size} ms-xl{size}"),
style = style,
Stack(
tokens = list(childrenGap = 5),
Text(variant = "large", title, block = TRUE),
content
)
)
}
# create base page (without header and footer)
query_page <- makePage(
div(
Stack(
horizontal = T,
tokens = list(childrenGap = 10),
makeCard('Choose Data', data, size = 3),
makeCard('Current selections', selection, size = 3)
),
uiOutput('layout')
)
)
# function to create layout of header, panes, and footer
layout <- function(mainUI) {
div(class = 'grid-container',
div(class = 'header', header),
div(class = 'main', mainUI)
)
}
#' @export
ui <- function(id) {
ns <- NS(id)
fluentPage(
layout(query_page)
)
}
#' @export
server <- function(id) {
moduleServer(id, function(input, output, session) {
cols_selected <- data$server('cols')
selection$server('selection', cols_selected)
})
}
型
---main.R---
box::use(
shiny[tagList, moduleServer, NS],
)
# import modules to main app
box::use(
app/view/layout
)
#' @export
ui <- function(id) {
ns <- NS(id)
tagList(
data$ui(ns('data')),
layout$ui(ns('layout'))
)
}
#' @export
server <- function(id) {
moduleServer(id, function(input, output, session) {
data_module <- callModule(data$server('data'))
cols_selected <- data_module$cols_selected
selection$server('selection', cols_selected)
layout$server('layout')
})
}
型
---app.R---
# Rhino / shinyApp entrypoint. Do not edit.
rhino::app()
型
我试过观察和obeserveEvent,但没有工作。我认为主要的问题是我引用每个模块的服务器端到main.R脚本的方式,但我不能找出正确显示数据的组合。
1条答案
按热度按时间0ve6wy6x1#
问题似乎在于模块和主应用程序之间如何传递React值。要正确处理React性并确保正确显示选择,可以对代码进行以下更改:
在data.R模块中:
您需要修改服务器函数以返回响应值cols_selected,而不是将其放入列表中。
字符串
在selection.R模块中:
通过调用前面创建的函数,确保从data.R模块中正确检索React值cols_selected。
型
在main.R模块中:
在检索cols_selected reactive值的方式中有一个小错误。你应该使用data_module对象,而不是直接使用data$server('data')函数。
型
通过进行这些更改,React性应正确工作,并且用户所做的选择将显示在选择模块中,而无需导航回下拉列表。