【发布时间】:2018-08-24 15:07:10
【问题描述】:
(我通读了this 问题,尽管标题相似,但它与我的问题无关——或者,如果是的话,我太笨了,看不出它是如何应用的。)
我正在模块化我的 Shiny 代码,以便添加额外的图表只需要在单独的文件中添加几个函数。存在三个面板——侧面板(用户在其中选择图形)、底部面板(用户在其中选择图形参数)和主面板(在其中显示图形)。
侧面板不变,但底部面板会根据侧面板中的选择而变化。
side_panel.R
# UI function
sidePanelInput <- function(id, label='side panel') { # Some input w/ ns = selected_graph }
# Server function
sidePanel <- function(input, output, session) {
selected_graph <- reactive({input$selected_graph})
return(selected_graph)
在我的 app.R 文件中,selected_graph 被传递到底部面板和主面板:
app.R
# ...
sidePanel <- callModule(sidePanel, 'side')
bottomPanel <- callModule(bottomPanel, 'bottom', data=some_data, selected_graph=sidePanel)
mainPanel <- callModule(mainPanel, "main", data=some_data, selected_graph=sidePanel, params=bottomPanel)
# ...
到目前为止一切都很好(注意bottomPanel 也返回了一些东西,然后传递给了mainPanel)。所有这些来回传递都很好。这是我的问题:每个图表的底部面板都不同,并在单独的文件中定义。这意味着bottomPanel 模块需要知道从sidePanel 吐出的反应中渲染什么。这也意味着我不使用bottomPanel的UI功能,我只使用renderUI的服务器功能:
bottom_panel.R
source('graphs')
bottomPanel <- function(input, output, session, data, selected_graph) {
# Call the function of the graph, depending on what the selected graph is
output$bottomPanel <- renderUI({
tagList(
match.fun(paste(selected_graph(), '_bottom_panel', sep=''))(session$ns('id'))
)
})
# So, if the selected graph is 'scatter_1', then the function call will be
# scatter_1_bottom_panel(session$ns('id')) -- An example of a bottom_panel function
# is provided at the end of this question, but it works as intended
# Now, we set the defaults (specific to the graph); for example, slider-ranges
# will be set according to mins and maxes in the data. Similar to above, a
# match.fun() call is used here to determine how the defaults are set
observe({
match.fun(paste(selected_graph(), '_bottom_panel_defaults', sep=''))(session, data)
})
# Here is my problem. I need to output the parameters of the newly-rendered
# bottom panel, so that those parameters can be passed to the main panel. This
# as it is doesn't work, because one apparently can't read from server output
params <- reactive({output$bottomPanel})
return(params)
}
渲染后的UI在渲染并调用默认值函数后如何输出参数?
example_bottom_panel.R
scat_2_bottom_panel <- function(id) {
ns <- NS(id)
panel <- wellPanel(
sliderInput(
inputId = ns('duration_range'),
label = 'Duration of Sound [ms]',
min = 0,
max = 10000,
value = c(0, 10000),
step = 100,
round = FALSE,
ticks = TRUE
)
)
return(panel)
}
example_default_function.R
scatter_1_bottom_panel_defaults <- function(session, data) {
updateSliderInput(session, 'duration_range', value=c(min(data$duration), max(data$duration)))
}
我已经阅读了上面链接的问题几次,似乎这是在服务器功能中所做的:
xvar <- reactive({input[[ "xvar" ]] })
yvar <- reactive({input[[ "yvar" ]] })
然后xvar 和yvar 被用作renderUI 调用中的参数。乍一看,这对我不起作用;每个底部面板所需的反应值根据用户选择的图表而变化。也许我可以在 bottom_panel 函数中包含 renderUI 调用,将这些 ID 声明为响应式,然后在面板生成中使用它们?
【问题讨论】:
-
你能做一个小的复制例子吗?如果我理解正确,您想让侧面板返回一些由底部面板动态使用的反应值吗?
-
@KotaMori 不完全是。我想让底部面板返回在服务器函数的
renderUI调用中生成的参数(以便这些可以传递到主面板)。渲染的 UI 通过单独的函数调用,并取决于侧面板的选择。我将处理一个小的复制示例,但我担心它不会比我上面发布的小很多! -
@KotaMori 重申一下,我的问题不是从侧面板获取反应值并将其传递到底部面板,而是从底部面板发送值(从变量 @ 987654339@ 调用,不是来自 UI 函数)
-
我明白了......也许问题是“输出”不是反应对象,所以我们不能像“输入”那样传递。你到底想通过什么?我认为通过
output$bottomPanel没有意义。也许您想传递“来自动态创建的 UI 的输入”? -
@KotaMori 是的!这正是我想要通过的。我只是不确定如何从服务器功能中做到这一点(因为这是呈现 UI 的地方)。现在,我正在尝试将 UI 创建函数中的 ID 声明为响应式,然后在函数本身中返回这些 ID。