R 动态显示仪表板页面

R 动态显示仪表板页面,r,shiny,shinydashboard,R,Shiny,Shinydashboard,我有一个功能强大的闪亮应用程序,它使用了shinydashboard软件包 新功能需要特定于用户的行为(例如,为不同的用户名使用不同的数据集)。因此,我打算 显示登录表单 验证凭据,如果成功,则将响应值LoggedIn设置为true 只要LoggedIn设置为TRUE 我的方法基于,它根据反应值决定在renderUI中显示哪个元素 以下简化示例用于在单击操作按钮后更改显示的UI元素。源代码之间的唯一区别是示例1(按预期工作)使用的是固定页面,而示例2(不工作-单击按钮不会切换到ui2)使用的是仪

我有一个功能强大的闪亮应用程序,它使用了
shinydashboard
软件包

新功能需要特定于用户的行为(例如,为不同的用户名使用不同的数据集)。因此,我打算

  • 显示登录表单
  • 验证凭据,如果成功,则将响应值
    LoggedIn
    设置为
    true
  • 只要
    LoggedIn
    设置为
    TRUE
  • 我的方法基于,它根据反应值决定在
    renderUI
    中显示哪个元素

    以下简化示例用于在单击
    操作按钮后更改显示的UI元素。源代码之间的唯一区别是示例1(按预期工作)使用的是
    固定页面
    ,而示例2(不工作-单击按钮不会切换到
    ui2
    )使用的是
    仪表板页面

    工作示例

    library(shiny)
    
    ui1 <- fixedPage(actionButton("btn_login", "Login"))
    ui2 <- fixedPage(sliderInput("slider", "slider", 3, 2, 2))
    ui <- uiOutput("ui")
    
    server <- function(input, output, session) {
      state <- reactiveValues(LoggedIn = FALSE)
      output$ui <- renderUI({if (!state$LoggedIn) ui1 else ui2})
    
      observeEvent(input$btn_login, {
        state$LoggedIn = TRUE
      })
    }
    
    shinyApp(ui, server)
    
    library(shiny)
    library(shinydashboard)
    
    ui1 <- fixedPage(actionButton("btn_login", "Login"))
    ui2 <- dashboardPage(dashboardHeader(), dashboardSidebar(), dashboardBody())
    ui <- uiOutput("ui")
    
    server <- function(input, output, session) {
      state <- reactiveValues(LoggedIn = FALSE)
      output$ui <- renderUI({if (!state$LoggedIn) ui1 else ui2})
    
      observeEvent(input$btn_login, {
        state$LoggedIn = TRUE
      })
    }
    
    shinyApp(ui, server)
    
    5月29日编辑

    @贝蒂尔男爵

    你的意思是这样的吗

    loginUI <- fixedPage(actionButton("btn_login", "Login"))
    mainUI <- # See below
    ui <- loginUI
    
    server <- function(input, output, session) {
      observeEvent(input$btn_login, {
        removeUI(selector = "body")
        insertUI(selector = "head", where = "afterEnd", mainUI)
      })
    }    
    shinyApp(ui, server)
    

    loginUI它也可以与
    invalidaterater()
    一起使用,但也只能临时使用

    library(shiny)
    library(shinydashboard)
    
    ui <- uiOutput("ui")
    
    server <- function(input, output, session) {
    
      state <- reactiveValues(LoggedIn = FALSE)
    
      observeEvent(input$btn_login, {
        state$LoggedIn = !state$LoggedIn
      })
    
      ui1 <- reactive({
        fixedPage(actionButton("btn_login", "Login"))
      })
    
      ui2 <- reactive({
        ui2 <- dashboardPage(dashboardHeader(), dashboardSidebar(), dashboardBody(
           sliderInput("slider", "slider", min = 1, max = 10, value = 2)
         ))
        invalidateLater(100, session)
        ui2
      })
    
      output$ui <- renderUI({if (!state$LoggedIn) ui1() else ui2()})
    
    }
    
    shinyApp(ui, server)
    
    库(闪亮)
    图书馆(shinydashboard)
    
    ui不确定这是您想要的解决方案,但下面是我尝试使用的
    shinyjs
    和一些CSS。从
    固定页面
    切换到
    仪表板页面
    似乎很难,因此如果您真的想使用
    shinydashboard
    ,我会坚持使用
    shinydashboard
    ,并禁用登录页面上的仪表板外观

    library(shiny)
    library(shinyjs)
    library(shinydashboard)
    
    ui1 <- div(
      id = "login-page",
      actionButton("btn_login", "Login")
    )
    
    ui2 <- hidden(    
      div(
        id = "main-page",
        sliderInput("slider", "slider", 3, 2, 2)
      )
    )
    
    ui <- dashboardPage(dashboardHeader(), 
                        dashboardSidebar(collapsed = TRUE), 
                        dashboardBody(useShinyjs(),
                                      tags$head(
                                        tags$style(
                                          HTML('.main-header {
                                                  display: none;
                                                }
    
                                                .header-visible {
                                                  display: inherit;
                                                }')
                                        )
                                      ),
                                      fluidPage(ui1, ui2)
                        )
    )
    
    server <- function(input, output, session) {
    
      state <- reactiveValues(LoggedIn = FALSE)
    
      observeEvent(input$btn_login, {
        state$LoggedIn = TRUE
        shinyjs::addClass(selector = "header", class = "header-visible")
        shinyjs::removeClass(selector = "body", class = "sidebar-collapse")
        shinyjs::hide(id = "login-page")
        shinyjs::show(id = "main-page")
      })
    
    }
    
    shinyApp(ui, server)
    
    库(闪亮)
    图书馆(shinyjs)
    图书馆(shinydashboard)
    
    你退房了吗?所以,我认为你不能创建这样的仪表板页面。谢谢你的回答。事实上,我读过这些。请考虑编辑后的帖子!您好,您的问题与输入和输出的绑定有关。登录后重写完整的ui有多重要?使用
    insertUI
    removeUI
    可以做一些更稳定的事情。这也是一个解决方案吗?@BertilBaron嘿,谢谢,我已经更新了我的问题!如果我理解正确的话。您不希望用户看到仪表板标题等。。直到他登录?嘿,再次感谢你的回复。不幸的是,这个例子经常使ui2失效,不是吗?例如,在本例中,滑块输入将每100ms重置为其初始值。正确。我在仪表板或任何ui中都没有滑块输入。我刚刚看到从fluidPage切换到dashboard。不过,我想知道为什么会有这种转变。由于shinyjs的
    delay
    ,我运气不佳。不过这可能会有所帮助。这是一个如何重写invalidateLater()函数的示例。感谢您的努力-我尝试了并使用了
    !声明$LoggedIn
    作为新的
    invalidateLater
    功能的条件。按“登录”按钮(如预期)后,该功能将运行一次,但该按钮仍可见,且不显示仪表板页面…:/这似乎在浏览器(Ffox)中起作用。在RStudio窗口中,我只看到了滑块,没有仪表板。哦,对了,谢谢注意,谢谢编辑。我也做了编辑。不管怎样,我只是浏览了一下评论,这看起来像是@gunnar.s谈论的“丑陋的解决方案”。。。
    library(shiny)
    library(shinyjs)
    library(shinydashboard)
    
    ui1 <- div(
      id = "login-page",
      actionButton("btn_login", "Login")
    )
    
    ui2 <- hidden(    
      div(
        id = "main-page",
        sliderInput("slider", "slider", 3, 2, 2)
      )
    )
    
    ui <- dashboardPage(dashboardHeader(), 
                        dashboardSidebar(collapsed = TRUE), 
                        dashboardBody(useShinyjs(),
                                      tags$head(
                                        tags$style(
                                          HTML('.main-header {
                                                  display: none;
                                                }
    
                                                .header-visible {
                                                  display: inherit;
                                                }')
                                        )
                                      ),
                                      fluidPage(ui1, ui2)
                        )
    )
    
    server <- function(input, output, session) {
    
      state <- reactiveValues(LoggedIn = FALSE)
    
      observeEvent(input$btn_login, {
        state$LoggedIn = TRUE
        shinyjs::addClass(selector = "header", class = "header-visible")
        shinyjs::removeClass(selector = "body", class = "sidebar-collapse")
        shinyjs::hide(id = "login-page")
        shinyjs::show(id = "main-page")
      })
    
    }
    
    shinyApp(ui, server)