【发布时间】:2020-01-28 19:21:52
【问题描述】:
我想在我的 Shiny 应用程序中拥有两个输入控制器实例,但我认为我必须做的是拥有两个输入并在其他输入发生变化时更新每个输入的值。这样,尽管它们具有不同的 ID,但它们在用户看来是相同的控件。
我预计会被告知不要做我想做的事情,但用例是我在 dashboardPage() 中有许多选项卡,其中只有两个共享控件。因此,将这两个页面的控件放在侧边栏中会使用户感到困惑。
我根据closely-related question 做了一个简单的、可行的示例来说明如何执行此操作(使用仪表板更清楚地说明我为什么要这样做),并通过说服提问者做其他事情来回答(这在他们的情况下工作,但在我的情况下没有工作)。该应用程序运行良好,只是随着它变得越来越复杂,计算有时需要足够长的时间,以至于我可以更改一个输入,然后在 Shiny 服务器有时间更新值之前更改另一个输入。这会导致无限反馈(输入 1 更新以匹配输入 2,而输入 2 更新以匹配输入 1,然后只要我愿意观看,这种情况就会重复)。
library(shiny)
library(shinydashboard)
ui = dashboardPage(
dashboardHeader(title = "Example"),
dashboardSidebar(
sidebarMenu(
menuItem("Tab 1", tabName = "tab1", icon = icon("chart-line")),
menuItem("Tab 2", tabName = "tab2", icon = icon("chart-line")),
menuItem("Other Tab", tabName = "tab3", icon = icon("project-diagram"))
)
),
dashboardBody(
tabItems(
# First tab content
tabItem(tabName = "tab1",
# Input first number
numericInput("input1", label = "Input 1", value = 1, min=1, step=1)
),
# Second tab content
tabItem(tabName = "tab2",
# Input second number
numericInput("input2", label = "Input 2", value = 1, min=1, step=1)
),
# Third tab content
tabItem(tabName = "tab3", "Unrelated content")
)
)
)
server = function(input, output, session) {
# Update inputs to match each other
observeEvent(input$input1, {
updateSelectInput(session = session,
inputId = "input2",
selected = input$input1)})
observeEvent(input$input2, {
updateSelectInput(session = session,
inputId = "input1",
selected = input$input2)})
}
shinyApp(ui = ui, server = server)
问题:有哪些其他方法可以让单独的页面具有控制两个页面的匹配控件,但不必将这些控件放在每个页面上?子问题:这些方法中是否有任何一种方法可以避免无限循环问题?推论:我看到一篇文章,我认为是从辅助脚本渲染 UI 页面并将输入参数传递给这些脚本的 URL,这似乎是一个很好的策略,但我现在找不到这篇文章并且正在努力弄清楚我自己。
【问题讨论】:
标签: r shiny shinydashboard shiny-reactivity