如何从Elm中的组件调用父msg?

时间:2016-08-08 11:00:08

标签: elm elm-architecture

我有一个模态窗口,可以在其中显示不同的组件。每个组件都有自己的更新程序和消息,但我想在它们之间共享一个关闭按钮。

因此,我无法呼叫" CloseModal"直接来自我的孩子 - 榆树不允许我给别人打电话。我有什么选择?

我以为我可以调用" Modal.Update.update Modal.Messages.CloseModal",但在我的组件中我只有一个州的块。所以它不是一个选择。

然后我找到了一种将消息从父母传递给孩子的方法,但它并没有帮助我以其他方式传递消息。或兄弟姐妹。

1 个答案:

答案 0 :(得分:10)

简而言之,您无法直接将消息从子节点传递给父节点或兄弟节点。

Elm Architecture实现单向消息传递,换句话说,在子组件收到消息之前,您的父组件始终知道子组件的消息。

我做了一个简单的example of parent-child communication,它太大了,无法将其嵌入到答案中,因此我只会在此处注明关键点。

子组件定义set of Messages

type Msg
    = Update Model
    | Focus
    | Blur

在其update函数中,我们ignore消息,用于父组件。

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Update value ->
            ( value, Cmd.none )

        -- Ignore the rest of the messages.
        _ ->
            ( model, Cmd.none )

在父{q} update函数中,我们可以模拟匹配所需的消息并对它们作出反应。

其余消息将通过default branch

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        NameMsg childMsg ->
            case childMsg of
                {- We have intercepted a message from child component.
                   This part of the update function might be moved
                   to a separate function for better readability.
                -}
                Input.Focus ->
                    update (HelperMsg Helper.Show) model

                Input.Blur ->
                    update (HelperMsg Helper.Hide) model

                -- The default message passing routine.
                _ ->
                    let
                        ( nameModel, nameCmd ) =
                            Input.update childMsg model.name
                    in
                        ( { model | name = nameModel }
                        , Cmd.map NameMsg nameCmd
                        )

上面的示例总结了子父母和兄弟姐妹的沟通。您可以使用任何组件的任何消息以递归方式运行更新函数。

从孩子的update功能

发送消息

Cmd.Extra公开了一个发送消息的功能。

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model ->
    (model, message SomeMessage)

PS:翻译模式示例在我的待办事项上,如果您希望我用它来更新答案,请留言。