Open zilch42 opened 2 years ago
Hello @zilch42, thanks for reaching out!
If I recall correctly there's no documentation on how to use shiny.router
with modules, but please take a look at this modification of your example:
library(shiny)
library(shiny.fluent)
library(shiny.router)
# navigation pane objects
navigation_styles <- list(
root = list(height = "100%", width = "30%", boxSizing = "border-box",
border = "1px solid #eee", overflowY = "auto"))
link_groups <- list(
list(
links = list(
list(name = 'Home', url = '#!/', key = 'home'),
list(name = "Documents", key = "documents", url = '#!/documents'),
list(name = "Pages", key = "pages", url = '#!/pages')
)))
# page UIs
home_page_ui <- tagList(p("Homepage"))
documents_page_ui <- function(id){
ns <- NS(id)
tagList(textOutput(ns("title")))
}
pages_page_ui <- function(id){
ns <- NS(id)
tagList(textOutput(ns("title")))
}
# page servers
documents_page_server <- function(documents_id = "documents1", documents_text = reactive("placeholder")){
moduleServer(documents_id, function(input, output, session){
ns <- session$ns
output$title <- renderText(documents_text())
})
}
pages_page_server <- function(pages_id = "pages1", pages_text = reactive("placeholder")){
moduleServer(pages_id, function(input, output, session){
ns <- session$ns
output$title <- renderText(pages_text())
})
}
# Creates router. We provide routing path, a UI as
# well as a server-side callback for each page.
router <- make_router(
route("/", home_page_ui),
route("documents", documents_page_ui("documents1"), documents_page_server),
route("pages", pages_page_ui("pages1"), pages_page_server)
)
shinyApp(
ui = fluidPage(
Nav(
groups = link_groups,
selectedKey = "home",
styles = navigation_styles
),
fluidPage(
router$ui
)
),
server = function(input, output, session) {
router$server(
input,
output,
session,
pages_id = "pages1",
documents_id = "documents1",
pages_text = reactive("Pages Page"),
documents_text = reactive("Documents Page")
)
}
)
In router$server
function code there's this line:
lapply(routes, function(route) route$server(input, output,
session, ...))
which hints us that we can use ellipsis to pass arguments to server functions. We just need to make those arguments names unique, that's why I've used documents_id
and pages_id
instead of usual id
.
Does this example help you solve your issue?
Thanks @jakubsob. I've applied that method to my app and it works so that's great. I haven't noticed any change in behaviour though. The app still seems to load all pages initially not just the page being viewed, and if I change a reactive value (eg a data filter) that affects other pages they all recalculate at once regardless of which page is currently being viewed. Is that currently still expected behaviour? That's what I was hoping this method would solve
It may be a while after the creation of this issue but I would like to second it. Is shiny.router still supported/developed? Appsilon/rhino for example proposes the use of moduleServer
and modules as well but doesn't mention shiny.router
.
Hi @FMKerckhof, shiny.router
is passively maintained now. This means that we don't expect to add any new features soon. shiny.router
is a package for routing - you can create an app that uses routing or not depending on your requirements. It's an optional feature and rhino
doesn't encourage you nor it disencourages you from using it.
We'll try to reinvestigate this issue and come back with a solution
Hi @jakubsob ,
Thanks for your clarifications especially with respect to feature development.
In the package description you do however mention to make it possible tocustomize loading full session or just visible part in the future. That is a big topic I am struggling with because I usually create dashboards that do have database queries but also use global variables. So, these change the full session and all the queries get refreshed. You guys have a solution for that in your backpack?
Best Michael
Related (modules rhino router): https://github.com/Appsilon/NLPShiny/blob/main/app/layouts/pages.R check out corresponding modules on view folder, related: https://stackoverflow.com/questions/71753556/how-to-make-conditionalpanel-work-with-box-with-rhino
without rhino: https://github.com/Appsilon/possible_example
hi there,
I have a reasonably large app using shiny.fluent and shiny.router (thanks for these packages they are really great), with a structure similar to the code below:
Each of my pages are inside modules because they are quite similar and it helps me avoid namespace conflicts. Notice that my page servers are just in the main server function, not in the router.
This works okay, but suffers from the issue of every page reloading when something changes, not just the current page ( #70). From what I understand from reading other issues, this issue has been fixed in the current version of shiny.router, but requires calling the page server from the router - ie. using
route(path, ui, server = ACTUAL_SERVER_FUNCTION)
. Is that correct?I can only get that to work if the pages are not modules that use moduleServer(). Is there any way to get
route
to work with modules? And is there any way to pass parameters (e.g. a set of reactive values) to those server modules if it does work?Cheers