首页 > 解决方案 > 在模块之间发送消息

问题描述

在使用可重用组件时,不太清楚如何在模块之间发送消息。

我有一个扩展的文本区域,我想在网站上的多个不同部分使用它。文本区域接受构成用户操作的部分 HTML。通常处理提交、取消、上传图标等。

试图写一个我正在谈论的快速示例,而不在这里抛出大量代码。所以本质上,我只想插入和播放已经附加的 HTML 片段。

我假设 CancelNote 作为 TextArea 消息被触发,所以它永远不会看到 Cancel Note 消息。不知道我将如何在这里使用 Html.map(或者即使我会)......感觉即插即用方法可能是一种不好的方法,但不确定我还能如何实现体面的可重用性。

SEPERATE MODULE

update model msg =
    case msg of
        CancelText ->
            ( { model | note = (Just "") }
            , Cmd.none
            )


view: stuff
view stuff = 
......
    TextArea.view 
         (button [ Html.Events.onClick CancelText] [])






TEXT AREA MODULE 


view : Html.Html msg -> Html msg
view actionHtml =
    div [ class "extended_text_area_container" ] [
        textarea [] [
        ]
        , actionHtml
    ]

标签: elm

解决方案


消息就像任何其他值一样只是值。您可以直接传递它们:

-- SEPERATE MODULE


view: stuff
view stuff = 
......
    TextArea.view CancelText



-- TEXT AREA MODULE 


view : msg -> Html msg
view msg =
    div [ class "extended_text_area_container" ]
        [ textarea [] []
        , button [ onClick msg ] []
        ]

编辑:如果您还需要维护内部状态,只需使用另一条消息告诉父级更新状态:

-- Main module


type msg =
    ...
    SetTextAreaState TextArea.state


update model msg =
    case msg of
        ...
        SetTextAreaState state ->
            { model | textAreaState = state }


view : Model -> Html msg
    TextArea.view SetTextAreaState model.textAreaState



-- TextArea module

type State =
    ...

type Msg =
    Clicked


update : State -> Msg -> State
update state msg =
    case msg of
        Clicked ->
            { state | clicked = True }


view : (State -> msg) -> State -> Html msg
view toMsg state =
    let
        updateAndWrap msg =
            toMsg (update state msg)
    in
    div [ class "extended_text_area_container" ]
        [ textarea [] []
        , button [ onClick (updateAndWrap Clicked) ] []
        ]

在这里,不是直接将 a 传递msgonClickin ,而是TextArea.view调用一个更新状态的函数,然后将其包装msg在从父级传入的构造函数中,这将产生一个我们不知道的类型的消息。

此外,虽然我使用类似于整体 Elm 架构的内部Msg类型和update功能,但这绝不是强制性的。这只是一种很好的方法,因为它很熟悉并且可以很好地扩展。


推荐阅读