In short, you can not pass messages directly from child to parent or a sibling.
Elm Architecture implements uni-directional message passing, in other words, your parent component is always aware of messages for child components before child component will receive a message.
I have made a simple example of parent-child communication, it is way too big to embed it into an answer so that I will note only the key points here.
Child
Child component defines a set of Messages:
type Msg
= Update Model
| Focus
| Blur
In it's update
function we ignore Messages, intended for the parent component.
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Update value ->
( value, Cmd.none )
-- Ignore the rest of the messages.
_ ->
( model, Cmd.none )
Parent
In parent's update
function we can pattern match required messages and react to them.
The rest of the messages will go through default branch.
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NameMsg childMsg ->
case childMsg of
{- We have intercepted a message from child component.
This part of the update function might be moved
to a separate function for better readability.
-}
Input.Focus ->
update (HelperMsg Helper.Show) model
Input.Blur ->
update (HelperMsg Helper.Hide) model
-- The default message passing routine.
_ ->
let
( nameModel, nameCmd ) =
Input.update childMsg model.name
in
( { model | name = nameModel }
, Cmd.map NameMsg nameCmd
)
The example above concludes the child-parent and sibling communication. You can run the update function recursively as much as you want with any messages to any components.
Sending Messages from child's update
function
Cmd.Extra exposes a function for sending messages.
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model ->
(model, message SomeMessage)
PS: Translator pattern example is on my To-do, leave a comment if you want me to update the answer with it.