永久存储来自一个操作按钮的输入,以便以后使用

时间:2018-07-23 17:48:44

标签: r shiny shinydashboard

我有一个仪表板(我是使用“ shinydashboard”软件包制作的)。

仪表板的用途

仪表板在不同的选项卡中显示不同季度的查询结果,每个选项卡中都有单独的SQL查询。数据库中的模式仅授予某些用户访问权限,因此,如果未对用户进行身份验证,他将无法查看查询结果。

必需的操作

对于身份验证过程,仪表板的主页要求用户提供以下信息

  • 用户名
  • 密码
  • 最新季度(将在SQL查询中用作输入)
  • 倒数第二个季度(在SQL查询中用作输入)

问题(有关用户界面和服务器,请参见下面的示例代码)

一旦用户单击“ home_act”操作按钮,我想存储该值以在所有其他选项卡中使用。每个选项卡将具有一个“ tab_ {no} _act”操作按钮,单击该按钮将使用来自主选项卡的存储输入中的值来产生相应选项卡的SQL查询结果。我不希望用户每次必须执行每个单独的选项卡时都返回并单击“ home_act”操作按钮。

仪表板的理想行为是:

  • 用户打开仪表板,在“主页”选项卡上输入凭据。
  • 转到“表1”,单击“提交”并获取sql tab_1查询结果
  • 转到“表2”,单击“提交”并获取sql tab_2查询结果。

    我尝试过使用reactValues()函数存储值并将它们传递给不同的反应堆,但是它不起作用。请让我知道我需要更改/应该使用哪个新功能。

可复制的示例代码

library(shinydashboard)
library(shiny)
library(data.table)
library(RPostgres)


ui <- dashboardPage(
  dashboardHeader(title = "Basic dashboard"),
  dashboardSidebar(
    sidebarMenu(
      menuItem("Home", tabName = "home"),
      menuItem("Tab 1", tabName = "tab_1"),
      menuItem("Tab 2", tabName = "tab_2")
    )
  ),
  dashboardBody(
    # Boxes need to be put in a row (or column)
    tabItems(
      # First tab content
      tabItem(tabName = "home",
              fluidPage(
                fluidRow(
                  column(3,offset = 0,
                         textInput(inputId = "home_latest_qtr",label = "Most Recent Quarter")),
                  column(3,offset = 0,
                         textInput(inputId = "home_pnltmt_latest_qtr",label = "Penultimate Latest Quarter")),
                  column(3,offset = 0,
                         textInput(inputId = "home_user",label = "Database Username")),
                  column(3,offset = 0,
                         passwordInput(inputId = "home_pwd",label = "Database Password")),
                  column(12,
                         actionButton(inputId = "home_act",label = "Home Submit"))
                  )
                )
      ),

      # Second tab content
      tabItem(tabName = "tab_1",
              fluidPage(
                fluidRow(
                  column(3,
                         actionButton("tab_1_act","Tab 1 Submit"))
                )
                ,
                dataTableOutput(outputId = "tab_1_output")

              )
      ),
      tabItem(tabName = "tab_2",
              fluidPage(
                fluidRow(
                  column(3,
                         actionButton("tab_2_act","Tab 2 Submit"))
                )
                ,
                dataTableOutput(outputId = "tab_2_output")

              )
      )
    )
  ))

server <- function(input, output) {
  user_credentials <- reactiveValues(user = '', pwd = '',latest_qtr = '',pnltmt_latest_qtr = '')
  observeEvent(input$home_act,{
    user_credentials$user <- input$home_user
    user_credentials$pwd <- input$home_pwd
    user_credentials$latest_qtr <- input$home_latst_qtr
    user_credentials$pnltmt_latest_qtr <- input$home_pnltmt_latest_qtr
  })

  tab_1_sql <- reactive({
    paste0("
           select * from table_1
           where quarter = '",user_credentials$latest_qtr,"' 
           limit 100
           ;")
  })

  tab_2_sql <- reactive({
    paste0("
           select * from table_1
           where quarter = '",user_credentials$pnltmt_latest_qtr,"' 
           limit 100
           ;")
  })

  tab_1_reactive <- reactive({
    if(user_credentials$user == '' | user_credentials$pwd == '')
    return()
    data.table::as.data.table(
      RPostgres::dbGetQuery(RPostgres::dbConnect(
        drv = RPostgres::Postgres(),
        host = "xyz.com",
        port = 1234,
        dbname = 'db',
        user = user_credentials$user,
        password = user_credentials$pwd), tab_1_sql())
    )

  })

  tab_2_reactive <- reactive({
    if(user_credentials$user == '' | user_credentials$pwd == '')
      return()
    data.table::as.data.table(
      RPostgres::dbGetQuery(RPostgres::dbConnect(
        drv = RPostgres::Postgres(),
        host = "xyz.com",
        port = 8888,
        dbname = 'db',
        user = user_credentials$user,
        password = user_credentials$pwd), tab_2_sql())
    )

  })

  output$tab_1_output <- renderDataTable({
    tab_1_reactive()
  })

  output$tab_2_output <- renderDataTable({
    tab_2_reactive()
  })

  }

shinyApp(ui, server)

1 个答案:

答案 0 :(得分:0)

经过这篇文章How to listen for more than one event expression within a Shiny eventReactive handler 的研究,我得到了一个使用observeEvent而不是reactValues的有效解决方案。 这是代码

library(shinydashboard)
library(shiny)
library(data.table)
library(RPostgres)

ui <- dashboardPage(
  dashboardHeader(title = "Basic dashboard"),
  dashboardSidebar(
    sidebarMenu(
      menuItem("Home", tabName = "home"),
      menuItem("Tab 1", tabName = "tab_1"),
      menuItem("Tab 2", tabName = "tab_2")    )
  ),
  dashboardBody(
    # Boxes need to be put in a row (or column)
    tabItems(
      # First tab content
      tabItem(tabName = "home",
              fluidPage(
                fluidRow(
                  column(3,offset = 0,
                         textInput(inputId = "home_latest_qtr",label = "Most Recent Quarter")),
                  column(3,offset = 0,
                         textInput(inputId = "home_pnltmt_latest_qtr",label = "Penultimate Latest Quarter")),
                  column(3,offset = 0,
                         textInput(inputId = "home_user",label = "Database Username")),
                  column(3,offset = 0,
                         passwordInput(inputId = "home_pwd",label = "Database Password")),
                  column(12,
                         actionButton(inputId = "home_act",label = "Home Submit"))
                )
              )
      ),

      # Second tab content
      tabItem(tabName = "tab_1",
              fluidPage(
                fluidRow(
                  column(3,
                         actionButton("tab_1_act","Tab 1 Submit"))
                )
                ,
                dataTableOutput(outputId = "tab_1_output")

              )
      ),
      tabItem(tabName = "tab_2",
              fluidPage(
                fluidRow(
                  column(3,
                         actionButton("tab_2_act","Tab 2 Submit"))
                )
                ,
                dataTableOutput(outputId = "tab_2_output")

              )
      )
    )
  ))

server <- function(input, output) {
  tab_1_sql <- reactive({
    paste0("
           select * from table_1
           where quarter = '",input$home_latest_qtr,"' 
           limit 100
           ;")
  })

  tab_2_sql <- reactive({
    paste0("
           select * from table_1
           where quarter = '",input$home_pnltmt_latest_qtr,"' 
           limit 100
           ;")
  })

  observeEvent(
    {input$home_act
      input$tab_1_act},{
        tab_1_reactive <- reactive({
        data.table::as.data.table(
      RPostgres::dbGetQuery(RPostgres::dbConnect(
        drv = RPostgres::Postgres(),
        host = "xyz.com",
        port = 1234,
        dbname = 'db',
        user = input$home_user,
        password = input$home_pwd), tab_1_sql())
    )

  })
  output$tab_1_output <- renderDataTable({
    tab_1_reactive()
  })
      })

  observeEvent({
    input$home_act
    input$tab_2_act},
    {
  tab_2_reactive <- reactive({
    data.table::as.data.table(
      RPostgres::dbGetQuery(RPostgres::dbConnect(
        drv = RPostgres::Postgres(),
        host = "xyz.com",
        port = 1234,
        dbname = 'db',
        user = input$home_user,
        password = input$home_pwd), tab_2_sql())
    )

  })
  output$tab_2_output <- renderDataTable({
    tab_2_reactive()
  })

  })
}

shinyApp(ui, server)