In the elm git book an architecture is described wherein child components generate messages which are disseminated via the main update function, eventually being handled by the appropriate update function in a child component. How does the translator pattern differ from this and what are the use cases of each pattern. Please provide a simple example.
Whenever you have a nested "component" with an update
function, you will need to make sure the parent passes through the child Msgs and Cmds. The git book outlines this with a simple example (where this code is in the parent, and Widget
is the child):
type Msg
= WidgetMsg Widget.Msg
update message model =
case message of
WidgetMsg subMsg ->
let
( updatedWidgetModel, widgetCmd ) =
Widget.update subMsg model.widgetModel
in
( { model | widgetModel = updatedWidgetModel }, Cmd.map WidgetMsg widgetCmd )
The above will be necessary any time a child has an update
function. However, the in the above example, the parent never knows or cares what child messages are being communicated to the child.
But now, consider the case that a parent needs to know about a Msg generated by a child. For instance: a game where a nested child component needs to communicate with a parent that the game is lost.
The Translator Pattern is useful when a parent component needs to react to a message returned from the child update function. Here is the basic structure of the update function in the linked example:
GameMsg internalMsg ->
let
(game_, cmd)
= Game.update internalMsg model.game
in
{ model | game = game_ } ! [ Cmd.map gameTranslator cmd ]
Notice that it looks a lot like the earlier update
example; the main difference is that rather than mapping the Cmd
directly to a blind parent Msg
(blind in that the single WidgetMsg
of the first example only passed around the child Msg
), the gameTranslator
mapping function allows you to map to one of the parent messages.
It may be helpful to read the Translator Pattern Blog Post in its entirety. It was written for Elm 0.17 so there are a few syntax changes, but the general idea still holds.