简体   繁体   中英

“Modular” Shiny App with Reusable Page

I want to design a Shiny app that is "modular" in the sense that I can reuse large parts of it in different applications. The app encompasses a multi-step workflow separated by different pages of a navbarPage or something similar. I basically want to make an entire page, including both UI and server logic, creatable from a pair of functions that I can then reuse in other applications to create the exact same page. The page is for gating flow cytometry data using a custom javascript widget I designed, but that's not important.

In short, there would be an R file with two functions. One, 'gatingPageUI', would return a tabPanel element containing all the UI elements of the page. It would take a 'prefix' argument and name all the inputs and outputs on the page '.gating.widget' or '.channel.x.select' or whatever, to avoid input/output name collisions.

The second function, 'gatingPageLogic', would take the same 'prefix' argument and assign reactive values to all the outputs and create observers to deal with changes in input. It would probably create a reactiveValues object, which would be updated with all the data generated by the page, and either return it or create it in the parent environment.

Problem is I do not know how to get and set reactive values from within the server logic function. If I pass a reactiveValues object to the function, will reactive objects (observers and reactive outputs) created in the function work correctly with it? For example, I would probably want to pass a ReactiveValues object containing the data set to operate on, can I access that within the function in a reactive way? What about returning reactive data? Can I just return a reactiveValues object or a reactive expression?

Or is this even the correct pattern to use?

One approach would be to just use source to include parts of one app in another app:

for(file in list.files(c("../base/tools/app", 
                          "../base/tools/data"),
                          pattern="\\.(r|R)$", full.names = TRUE))
      source(file, local = TRUE)

This approach would allow you to reuse chunks of code in different apps. Each app is in the same inst/ directory in my case and the code chunk above is in inst/quant. quant reuses the code in inst/base and extends it

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM