Example of Sibling/Nested component communication in elm.
The example tries to implement the accepted answer of this StackOverflow question
Please create issues with any feedback or leave comments in the SO question.
http://afcastano.github.io/elm-nested-component-communication/
- I have one parent component with two children. With the Elm Architecture, how can I update the right child when any of the counters in the left child change? Avoid the parent component to know about the internals of the children since it is not scalable.
- Each component will provide functions to access the data the parent needs and also expose Msg to update nested data. In this way, the parent component only need to know about the exposed functions and Msg of the direct child.
Counter.elm
exposes getNum
function to return the value of the counter without knowing the internal structure
and a new SetNum
Msg to update it:
type Msg
= Increment
| Decrement
| SetNum Int
...
getNum : Model -> Int
getNum model =
model.num
Pair.elm
also exposes a function to return the red number:
getRedNum : Model -> Int
getRedNum model =
Counter.getNum model.redCounter
and a new update Msg that is propagated to the update function of the Counter.
type Msg
= PairRed Counter.Msg
| PairGreen Counter.Msg
| UpdateRed Int
update : Msg -> Model -> Model
update msg model =
case msg of
UpdateRed value ->
{ model | redCounter = Counter.update (Counter.SetNum value) model.redCounter }
Main.elm
orchestrates the whole thing. Whenever a counter changes, it updates the other counter and the totals without knowing the internal structure of neither of them:
Pair1 subMsg ->
let
pair1 =
Pair.update subMsg model.pair1
totals =
Totals.update (Totals.UpdateRed <| Pair.getRedNum pair1) model.totals
pair2 =
Pair.update (Pair.UpdateRed <| Pair.getRedNum pair1) model.pair2
in
Model pair1 pair2 totals
To run it, simply do:
git clone git@github.com:afcastano/elm-nested-component-communication.git
cd elm-nested-component-communication
elm-reactor
go to http://localhost:8000/src/Main.elm
Thanks to rofrol for all the corrections made to this example.