Injection patterns for reactive models?
See original GitHub issueI have found the injection model to feel strangely backwards when used with reactive programming. I am using RxKotlinFX, which is backed by RxJava and RxJavaFX.
Here’s a little theory that might be driving this, and forgive me if I’m wrong on any assumptions. I’m not an expert on MVC at all.
Traditional imperative models would have the View
pull items from the Controller
, which would lazily trigger instantiating the Controller
. But a reactive model is likely to push items from the Controller
to the View
. It is an inversion of control.
So it is a little awkward to inject a Controller
into a View
, when really the View
should be injected into the Controller
. Otherwise, with the current injection pattern the View
will actually be doing all the work and not the Controller
.
If I’m not making any sense, try to think about migrating the reactive logic below from the View
to the Controller
. Unless I’m missing something, you might realize there is no way to accomplish this without a lot of messy initialization and anti-patterns to interop the two.
class MyApp: App() {
override val primaryView = MyView::class
}
class MyView: View() {
override val root = VBox()
val controller: MyController by inject()
var countLabel: Label by singleAssign()
var button: Button by singleAssign()
var itemsList: ListView<String> by singleAssign()
init {
with(root) {
button = button("Increment")
countLabel = label("")
itemsList = listview()
}
//everything else below needs to move to the Controller
//increment number on countLabel every time button is pressed
button.actionEvents()
.map { 1 }
.startWith(0)
.scan { x,y -> x + y }
.map { it.toString() }
.subscribe { countLabel.text = it }
//subscribe items into itemsList
controller.items.subscribe { itemsList.items.add(it) }
}
}
class MyController: Controller() {
val items = Observable.just("Alpha","Beta","Gamma","Delta","Epsilon")
}
Issue Analytics
- State:
- Created 7 years ago
- Comments:22 (10 by maintainers)
Top GitHub Comments
OK! I agree the above code looks clean and doesn’t present any problems that I can see. The View is supposed to contain view logic, so events emitted by the ui should be manipulated there. I’ll revisit this once I get more reactive experience and look for ways to optimize 😃
I think I’m overthinking this quite a bit. I’ve done a few experiments and I think I’m expecting too much from the
Controller
in a reactive setting, when really its role has not changed much.I believe the code I had earlier is acceptable. I think a “good design” might entail this:
Controller
View
should stay on theView
Controller
can hold hot Observables when it acts as an “event bus” of sorts between Views