Reputation: 5530
I have a feature called Editor
that I'm trying to plug into my app. Its view returns a the type Html EditorMsg
. I plug it in here:
edit : Editor.Types.Model -> Html EditorMsg
edit editorModel =
div [ class "edit" ] [ Editor.view editorModel ]
In the app, I have routing and so edit
is called by way of my main view
function, plus a couple of functions that manage which route to show:
-- VIEW
view : Model -> Html Msg
view model =
div []
[ RoutingMsg navBar
, EditorMsg (render model)
]
render : Model -> Html EditorMsg
render model =
case model.route of
Nothing ->
li [] [ text "Invalid URL" ]
Just route ->
showRoute route model
showRoute : Route -> Model -> Html EditorMsg
showRoute route model =
case route of
Home ->
home
Editor ->
edit model.editor
My view
also contains a navBar
as you can see, and that returns Html possibly containing a different type of message, RoutingMsg
:
navBar : Html RoutingMsg
navBar =
NavBarState.config
|> NavBarState.items
[ navItem "/" "Home" False
, navItem "/editor" "Edit" False
]
|> NavBar.view
This setup didn't compile because in view
I have a list of two different types, one returning Html RoutingMsg
and the other Html EditorMsg
, so I set up a union type to try to contain that difference:
type Msg
= RoutingMsg (Html RoutingMsg)
| EditorMsg (Html EditorMsg)
This seems to work, but then I run into trouble in my update method, where the matching doesn't quite work. Long and short of it is that it feels as though I've just got the wrong pattern. My goal was to make my Editor
somewhat independent, like a module, that can be plugged in different places. But it's hard for me to understand in Elm, how to integrate things.
To illustrate the problem more simply, I created this example on ellie-app that approximates what I tried to do but can't get working: https://ellie-app.com/PKmzsV3PC7a1/1
Is my approach here just incorrect, or if not, how can I get this code to work?
Upvotes: 1
Views: 868
Reputation: 6807
You should use Html.map to map children messages to the top-level Msg
Here's what you've been missing:
view : Model -> Html Msg
view model =
div []
[ Html.map ButtonDecMsg buttonDec
, div [] [ text (toString model) ]
, Html.map ButtonIncMsg buttonInc
]
Also the type annotation definition of child update functions should include the message type:
buttonDecUpdate : ButtonDecMsg -> Model -> Int
buttonDecUpdate msg model =
model - 1
Here is an example of working app: https://ellie-app.com/PM4H2dpFsfa1/0
Upvotes: 5