Reputation: 6861
In a few guides, message handling in parent components is made like this;
type Msg
= NavMsg Nav.Msg
| SidebarMsg Sidebar.Msg
| WidgetMsg Widget.Msg
And parent components handle them in updates with:
update : Msg -> AppModel -> (AppModel, Cmd 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)
_ ->
However, I couldn't find a simple way to do the same if the child components are inside a list. How can I tell the correct sub component to react to a message directed to him?
I thought of adding the component object to the message:
type Msg
= MessageToParent
| MessageToChild Child Child.Msg
But this seems very inefficient if the Child component is big, and still gives me trouble when trying to delegate the inner Child.Msg
to the right Child
.
What's the best way to handle message passing to a list of components?
Upvotes: 0
Views: 219
Reputation: 21047
I would suggest using an array (or Dict) and code like this
type Msg
= WidgetMsg Int Widget.Msg
update : Msg -> AppModel -> (AppModel, Cmd Msg)
update message model =
case message of
WidgetMsg idx subMsg ->
model.widgetModels
|> Array.get idx
|> Maybe.map (Widget.update subMsg)
|> Maybe.map (\(m,c) ->
({ model | widgetModels = Array.set idx m model.widgetModels }
, Cmd.map Widgetmsg idx c)
)
|> Maybe.withDefault (model, Cmd.none)
_ ->
Upvotes: 2