-
Notifications
You must be signed in to change notification settings - Fork 0
Description
component data is intentionally isolated from other components so as to encourage comprehensible component hierarchies. however, there are situations where accessing component data externally (and non-hierarchically) is a requirement.
Possible solutions
Hierarchical reactive data
One method of hierarchical and reactive data sharing is via defining reactive values on a top-level component and passing those along to subsequent child components.
E.g.
y <- component() {
data = function() {
list(
a = NULL
)
}
}
x <- component(
data = function() {
list(
rctv = shiny::reactiveVal()
)
}, template = function(ns) {
y(data = list(a = self$rctv))
}
)Barring the eventuality of a long chain of data passing, this has issues with understanding how data may mutate
Event bus
Like how vue does it -- basically just an event emitter
x <- event_bus()
x$emit()Isolated reactives
Wrapper class around shiny::reactiveVal and/or shiny::reactiveValues that isolates value access from the children of components with data. E.g.
x <- component(
data = function() {
list(
rctv = rsx::reactive_value()
)
}, template = function(ns) {
y(data = list(a = self$rctv))
}
)
y <- component() {
data = function() {
list(
a = NULL
)
}, methods = list(
setup = function(input, output, session) {
print(self$a) # legal usage
self$a <- self$a + 1L # illegal usage
}
)
}stateful object
Object that contains reactive values that can be accessed in any component, similar to vuex
my_store <- shiny::reactiveValues(
a = 1,
b = 2,
c = 3
)
x <- component(
data = function() {
a = my_store$a,
b = my_store$b,
c = my_store$c
}
)callback (child to parent)
x <- component(
data = function() {
list(
a = 1L,
update_a = function() {
self$a <- self$a + 1L
}
)
},
template = function(ns) {
y(data = list(cb = update_a))
}
)
y <- component() {
data = function() {
list(
cb = NULL
)
}, methods = list(
setup = function(input, output, session) {
self$cb()
}
)
}