Module Decorator Class
ShinyModule.Rd
This class is a decorator
and is not meant to be directly used, but to be
inherited by other Modules.
Details
Namespacing
The ShinyModule
class manages namespacing with the moduleName
and
instanceId
, to create a moduleId
. The moduleId
and parentNamespace
(when a module is nested in another module) make up the namespace
field.
moduleId = moduleName-instanceId
namespace = [parentNamespace-]moduleId
Server method
When creating a new module, the id
in shiny::moduleServer()
is set to
the moduleId
field.
Besides setting the id
, the initServer()
method is called at the start of
shiny::moduleServer()
. This initializes a reactive environment to be used
freely when developing modules. This method may be expanded upon to
initialize other namespace dependant features.
All of this is done by the class it self, in the public server()
method.
The server()
method calls the private private$.server()
, which should
overridden when creating a module.
As an example:
...
private = list(
.server = function(input, output, session) {
output$table <- shiny::renderTable(iris)
}
)
...
If the public server()
method is overridden an error will be thrown:
...
public = list(
server = function(input, output, session) {
output$table <- shiny::renderTable(iris)
}
)
...
myModule <- MyModule$new()
#> `self$server()` was overridden in `public = list(...)` override `private$.server()` instead in `private = list(.server = function(input, output, session) {})`
UI method
When accessing an outputId
in the UI, the namespace
field is used to
reference the correct namespace with shiny::NS()
.
It is also expected that the UI()
method returns all contents to be shown,
so if multiple things should be shown, they should be nested in, as an
exmaple, shiny::taglist()
.
As an example:
...
private = list(
.UI = function() {
# `private$.namespace` would also be valid.
shiny::tableOutput(outputId = shiny::NS(self$namespace, "table"))
}
)
If the public UI()
method is overridden an error will be thrown:
...
public = list(
server = function(input, output, session) {
output$table <- shiny::renderTable(iris)
}
)
...
myModule <- MyModule$new()
#> `self$UI()` was overridden in `public = list(...)` override `private$.UI()` instead in `private = list(.UI = function() {})`
Active bindings
instanceId
(
character(1)
) Random ID of 10 capitalized letters.parentNamespace
(
character(1)
) Namespace of the parent module.moduleName
(
character(1)
) Name of the module.moduleId
(
character(1)
) Module identifier, composed like:moduleName-instanceId
namespace
(
character(1)
) Namespace, composed like:[parentNamespace-]moduleName-instanceId
whereparentNamespace
is optionalreactiveValues
(
reactivevalues
) Reactive values. useshiny::isolate()
to get a non-reactive item from the reactive environment.
Methods
Method UI()
Method to include a tagList to include the body.
Method server()
Method to handle the back-end.
Examples
MyModule <- R6::R6Class(
classname = "MyModule",
inherit = ShinyModule,
private = list(
.UI = function() {
# `private$.namespace` would also be valid.
shiny::tableOutput(outputId = shiny::NS(self$namespace, "table"))
},
# Override server()
.server = function(input, output, session) {
output$table <- shiny::renderTable(iris)
}
)
)
if (interactive()) {
myModule <- MyModule$new()
preview(myModule)
}
# The following would throw an error for overwritnig the public UI() and server() methods:
MyModule <- R6::R6Class(
classname = "MyModule",
inherit = ShinyModule,
public = list(
UI = function() {
# `private$.namespace` would also be valid.
shiny::tableOutput(outputId = shiny::NS(self$namespace, "table"))
},
# Override server()
server = function(input, output, session) {
output$table <- shiny::renderTable(iris)
}
)
)
tryCatch({
myModule <- MyModule$new()
}, error = function(e) {
message(e)
})
#> Error in private$checkMethodOverrides(): `self$server()` was overridden in `public = list(...)` override `private$.server()` instead in `private = list(.server = function(input, output, session) {})`
#> `self$UI()` was overridden in `public = list(...)` override `private$.UI()` instead in `private = list(.UI = function() {})`
#> `self$server()` was overridden in `public = list(...)` override
#> `private$.server()` instead in
#> `private = list(.server = function(input,output, session) {})`
#> `self$UI()` was overridden in `public = list(...)` override
#> `private$.UI()` instead in `private = list(.UI = function() {})`