如何将来自不同elm功能的多个msg类型集成到顶级应用程序中

时间:2017-04-04 07:16:34

标签: elm

我有一个名为Editor的功能,我试图插入我的应用。其视图返回类型Html EditorMsg。我把它插在这里:

edit : Editor.Types.Model -> Html EditorMsg
edit editorModel =
    div [ class "edit" ] [ Editor.view editorModel ]

在应用中,我有路由,因此通过我的主edit函数调用view,以及管理要显示哪条路线的几个函数:

-- 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

如您所见,我的view还包含navBar,并且会返回可能包含不同类型消息的Html RoutingMsg

navBar : Html RoutingMsg
navBar =
    NavBarState.config
        |> NavBarState.items
            [ navItem "/" "Home" False
            , navItem "/editor" "Edit" False
            ]
        |> NavBar.view

这个设置没有编译,因为在view我有两个不同类型的列表,一个返回Html RoutingMsg而另一个Html EditorMsg,所以我设置了一个联合类型试图控制这种差异:

type Msg
    = RoutingMsg (Html RoutingMsg)
    | EditorMsg (Html EditorMsg)

这似乎有效,但是在我的更新方法中遇到了麻烦,匹配并不起作用。它的长短是因为我感觉好像是错误的模式。我的目标是让我的Editor有点独立,就像一个模块,可以插在不同的地方。但是我很难在榆树中理解如何整合东西。

为了更简单地说明问题,我在ellie-app上创建了这个示例,该示例近似于我尝试但无法正常工作的内容:https://ellie-app.com/PKmzsV3PC7a1/1

我的方法在这里是不正确的,或者如果没有,我怎样才能让这段代码起作用?

1 个答案:

答案 0 :(得分:4)

您应该使用Html.map将儿童消息映射到顶级Msg

这是你一直缺少的:

view : Model -> Html Msg
view model =
    div []
        [ Html.map ButtonDecMsg buttonDec
        , div [] [ text (toString model) ]
        , Html.map ButtonIncMsg buttonInc
        ]

子更新函数的类型注释定义也应包括消息类型:

buttonDecUpdate : ButtonDecMsg -> Model -> Int
buttonDecUpdate msg model =
    model - 1

以下是工作应用的示例:https://ellie-app.com/PM4H2dpFsfa1/0