Description
Hi,
I really like the ELM architecture that permits to bubble up the state and redispatch it to the tree in the update function.
Comparing it to React, this approach seems to permit to easily replace setState
of React components (local state) and put that state in a global model / atom.
However now imagine my app's domain is counters.
It is composed of:
- A pair of counters
- A list of counters
The business rule
Now I'd like to create a new component that will display a value based on the following rule:
- The value should increment by one on any counter increment
- The value should decrement by one on any counter decrement
- The value should never be more than 3 and less than 0 (if we increment with value 3, the value stays 3)
Now imagine the pair has actions:
type Action
= Reset
| Top Counter.Action
| Bottom Counter.Action
And the list has actions
type Action
= Insert
| Remove
| Modify ID Counter.Action
A sequence of actions like:
- Top Increment
- Top Increment
- Modify 1 Increment
- Bottom Increment
- Bottom Increment
- Modify 2 Decrement
The value for this sequence of action should be 2.
This business rule I want to implement might seem weird in this case but in the real world we often have to implement such rules...
The problem
How to create a model that receive these actions and then permit ti diplay that value?
The problem I see is that as the counter incrementations are "embedded" into parent actions, then we somehow need to pattern-match on the parent actions like Top / Bottom / Modify, before being able to see if the counter action is an increment.
It feels wrong to me, because tomorow if I need to add a new TupleX of counter, or Pyramid of counters or whatever with a strange shape, I don't want to have to manage additional pattern matching to compute the value I want.
If a simple "business event" (because counters is my business) increment was fired, then it would be much easier to listen to all these counter actions from any place of my app.
The idea would also be that to add my new view displaying the value I want, I should not need in any way to modify existing code normally. This is also the idea behind ideas like CQRS where you can spawn a new query view / index from an existing event log without having to rework at all the way events are emitted (because you can't erase the past anyway...)
Example needed
So here all the examples of this repository explains well how to handle local state.
However I do not see any example on how to implement real world business rules.
To compare with React I understand how to replace setState
with ELM, but I don't understand (by reading this tutorial) how to replace Flux.
I think that to solve my problem described above, I should not need to have a global understanding of the app inner workins. I should be able to see there is some kind of a global/business actions union-type with Increment and Decrement, and then just decide to listen from them, without having to know if these actions are fired from a pair or list of counters because my business rule simply don't care about that.
I'm pretty sure it is largely possible to do that in ELM and an example would be welcome from an experienced ELM user :)
I'm thinking of something like this:
view : Signal.Address Action -> Signal.Address BusinessAction -> Model -> Html
Can I make the counter view fire 2 actions in 2 distinct adresses like that? So that my counter click is fired both for local state update and also global / business listening from other components?
Thanks