发送初始消息时无法触发响应消息

时间:2017-08-24 02:27:14

标签: elm

发送初始消息时,我无法触发响应消息。

我有一个按钮:

  button
    [ class "register"
    , value "Create Account"
    , onClick Submit
    ]

我有以下消息:

type Msg
    = Submit
    | Response (Result Http.Error JsonProfile)

通过按钮单击调用的消息处理程序如下:

update : Msg -> Form -> ( Form, Cmd Msg )
update msg model =
    case msg of
        Submit ->
            ( model, runtime.tryRegister model Response )
        ...

以下是其他消息处理程序:

update : Msg -> Form -> ( Form, Cmd Msg )
update msg model =
    case msg of
        Submit ->
            ( model, runtime.tryRegister model Response )

        Response (Ok json) ->
            ( model, Navigation.load <| "/#/portal/1" )

        Response (Err error) ->
            ( model, Cmd.none )

我的tryRegister实现如下:

tryRegister : Form -> (Result Http.Error JsonProfile -> msg) -> Cmd msg
tryRegister form msg =

        let
            jsonProfile =
                JsonProfile 1 form.firstName form.lastName form.email

            newMsg v =
                msg
        in
            Cmd.map (newMsg <| Result.Ok jsonProfile) Cmd.none

这是上面描述的elm模块的客户端代码:

onRegistration : Registration.Msg -> Model -> ( Model, Cmd Msg )
onRegistration subMsg model =
    let
        ( form, _ ) =
            Registration.update subMsg model.registration
    in
        case subMsg of
            Registration.Submit ->
                ( { model | registration = form }, Cmd.none )

            Registration.Response result ->
                case result of
                    Result.Ok jsonProfile ->
                        let
                            newUser =
                                jsonProfileToProvider jsonProfile

                            newState =
                                { model
                                    | registration = form
                                    , portal =
                                        { initPortal
                                            | provider = newUser
                                            , requested = Domain.EditProfile
                                            , linksNavigation = False
                                            , sourcesNavigation = False
                                        }
                                }
                        in
                            ( newState, Navigation.load <| "/#/portal/" ++ getId newUser.profile.id )

                    Result.Err _ ->
                        ( model, Cmd.none )

期望:

我希望当我点击按钮时,会发生导航。 然而,没有任何反应,我不明白为什么。

Video

源代码为here

2 个答案:

答案 0 :(得分:2)

显然Cmd.map (...) Cmd.none不足以强制执行另一个更新周期。您可以通过Task.perform发送始终成功的任务来强制执行更新周期。

tryRegister : Form -> (Result Http.Error JsonProfile -> msg) -> Cmd msg
tryRegister form msg =
    JsonProfile 1 form.firstName form.lastName form.email
        |> Result.Ok
        |> msg
        |> Task.succeed
        |> Task.perform identity

注意:有充分的理由不这样做,outlined here,但我们现在将忽略那些适合您概述的框架

但是,仅此一项不会使您的代码有效。您有一个嵌套的update来电,忽略了从Cmd返回的Register.update

( form, _ ) =
    Registration.update subMsg model.registration

该下划线具有阻止从子update生成的所有命令的效果。您需要保留该子Cmd,将其映射到父Cmd,并在所有Cmd.none个案例中将其返回onRegistration。例如:

onRegistration : Registration.Msg -> Model -> ( Model, Cmd Msg )
onRegistration subMsg model =
    let
        ( form, subcmd ) =
            Registration.update subMsg model.registration

        regcmd =
            Cmd.map OnRegistration subcmd
    in
        case subMsg of
            Registration.FirstNameInput _ ->
                ( { model | registration = form }, regcmd )

            ...

答案 1 :(得分:0)

Cmd.none用于tryRegister函数,它不执行任何操作。我认为你应该使用Http.send在http请求完成后实际触发消息循环。

最短的例子......,

update msg model =
    case msg of
        Submit ->
            (model, Http.send Response request)

        Response ... -> 
            ...