У меня есть функциональное блестящее приложение, которое использует пакет shinydashboard
.
Новая функция требует специфичного для пользователя поведения (например, использование разных наборов данных для разных имен пользователей).Поэтому я намерен
- Показать форму входа
- Проверить учетные данные и установить реактивное значение
LoggedIn
в true
в случае успеха - Показать фактическое
dashboardPage
как только для LoggedIn
установлено значение TRUE
Мой подход основан на этом приложении , которое решает, какой элемент отображать в renderUI
на основе реактивногозначение.
В следующих упрощенных примерах предполагается изменить отображаемый элемент пользовательского интерфейса после нажатия actionButton
.Единственное различие между источником состоит в том, что в примере 1 (работает как задумано) используется fixedPage
, тогда как в примере 2 (не работает - нажатие кнопки не переключается на ui2
) используется dashboardPage
.
Рабочий пример
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)
Это связано с особенностями пакета shinydashboard
?Кто-нибудь имел подобную проблему (кроме этот пользователь ) и нашел решение?
Заранее спасибо за любую помощь!
РЕДАКТИРОВАТЬ
@ SeGa Это довольно бесполезное приложение отображает dashboardPage
после двойной активации reactiveTimer
- Может быть, есть возможность заставить его работать без таймера?
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)
timer <- reactiveTimer(1000, session)
output$ui <- renderUI({if (!state$LoggedIn) ui1 else ui2})
observeEvent(timer(), {
state$LoggedIn = !state$LoggedIn
})
}
shinyApp(ui, server)
РЕДАКТИРОВАТЬ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)
Теперь это работает, если mainUI
является одним из basicPage, bootstrapPage, fillPage, fixedPage, fluidPage, navbarPage
- новый тег body вставляется и отображается в DOM, но для bootstrapPage
.
эффект не действует, если вы намеревались изначально отобразить форму входа в dashboardBody
и заменить ее наактуальный контент после успешного входа - вот чего я хотел избежать.